def increment_template_usage_cache(service_id, template_id, created_at): key = cache_key_for_service_template_usage_per_day(service_id, convert_utc_to_aet(created_at)) redis_store.increment_hash_value(key, template_id) # set key to expire in eight days - we don't know if we've just created the key or not, so must assume that we # have and reset the expiry. Eight days is longer than any notification is in the notifications table, so we'll # always capture the full week's numbers redis_store.expire(key, current_app.config['EXPIRE_CACHE_EIGHT_DAYS'])
def wrapped(*args, **kw): # 存入redis的key key = ":".join(["ratelimit", by()]) # 获取单位时间内剩余的请求次数 try: remaining = requests - int(redis_store.get(key)) except (ValueError, TypeError): remaining = requests redis_store.set(key, 0) # 获取剩余单位时间周期的时间(秒) ttl = redis_store.ttl(key) if ttl < 0: # 已过期,则设置过期时间(ttl = -2, ttl = -1) redis_store.expire(key, window) ttl = window # 将rate limites情况写入g g.view_limits = (requests, remaining - 1, time.time() + ttl) if remaining > 0: # 剩余请求次数>0,则redis记录+1,并进入后续处理 redis_store.incr(key, 1) # 未达到限制次数,记录到g,方便dispatch处理 g.status_code = 200 return func(*args, **kw) else: # return make_response('Too Many Requests', 429) # 这里无法直接返回429,而是记录到g.status_code, 方便dispatch处理 g.status_code = 429 return func(*args, **kw)
def sigin(): username = request.form['username'] password = request.form['password'] user = db.get_by_id(table="tb_user", field="username", value=username) if not user or not pbkdf2_sha256.verify(password, user[0]['password']): return response(status_code=401, data="You Not Authorized") else: random_string = uuid.uuid4() raw_token = '{}{}'.format(random_string, username) access_token = hashlib.sha256(raw_token.encode('utf-8')).hexdigest() userdata = db.get_by_id(table="tb_userdata", field="id_userdata", value=user[0]['id_userdata']) stored_data = { 'id_userdata': user[0]['id_userdata'], 'email': userdata[0]['email'], 'username': username } dill_object = dill.dumps(stored_data) redis_store.set(access_token, dill_object) redis_store.expire(access_token, 3600) data = { 'email': userdata[0]['email'], 'Access-Token': access_token, 'expires': 3600 } return response(200, data=data)
def get_session(force=False): session = None if not force: session = redis_store.get(REDIS_KEY) if session: return session.decode() try: session = subprocess.check_output([ EJUDGE_CONTESTS_CMD_PATH, str(EJUDGE_CONTEST_ID), "master-login", "STDOUT", EJUDGE_USER_LOGIN, EJUDGE_USER_PASSWORD ]) session = session.strip() except: return None if not session: return None redis_store.set(REDIS_KEY, session) redis_store.expire(REDIS_KEY, TTL) return session.decode()
def post(self): """ 用户认证 :return: """ # 获取前端传参 req_data = request.get_json() username = req_data.get("username") password = req_data.get("password") # 判断数据是否为空 if not all([username, password]): return jsonify(code=RET.NODATA, codemsg="Username or Passowrd is None.") try: # 按用户查找数据是否存在 User_Data = Users_Models.query.filter_by(username=username).first() token = Users_Models.generate_auth_token(User_Data) except (IntegrityError, AttributeError) as e: current_app.logger.error(e) return jsonify(code=RET.NODATA, codemsg="User Data No Exist.") except Exception as e: current_app.logger.error(e) return jsonify(code=RET.DBERR, codemsg="Database Error.") try: # 从redis获取用户错误次数 Access_Nums = redis_store.get("access_login_error_number_%s" % username) except Exception as e: current_app.logger.error(e) else: # 判断redis访问错误是否为空或是否大于限制。 if Access_Nums is not None and int( Access_Nums) >= LOGIN_ERROR_MAX_TIMES: return jsonify(code=RET.REQERR, codemsg="Login errors are excessive.") # 判断用户是否存在或密码是否正确。 if User_Data is None or not User_Data.check_password(password): try: # 如果检测失败则保存信息到redis中,expire设置错误信息有效期 redis_store.incr("access_login_error_number_%s" % username) redis_store.expire("access_login_error_number_%s" % username, LOGIN_ERROR_FORBID_TIME) except Exception as e: current_app.logger.error(e) return jsonify(code=RET.DATAERR, codemsg="User or Password Auth Error.") return jsonify(code=RET.OK, codemsg="Succeed.", token=token)
def load_from_redis(cls, key, expire=0): redis_key = CLASS_TABLE % (cls.__name__, key) ret = redis_store.get(redis_key) if ret is None: return None try: ins = json.loads(ret) if expire != 0: redis_store.expire(redis_key, expire) except Exception, e: print("load from redis error for %s" % key) return None
def code(): """验证码""" infor = Code().creat_code() code_id = str(request.args.get('code_id') or '') redis_store.set(code_id, infor['code']) redis_store.expire(code_id, 30) image_path = infor["image_path"] #print(infor, code_id) with open(image_path, 'rb') as f: image_content = f.read() f.close() os.remove(image_path) return Response(image_content, mimetype='jpeg')
def update_bids(bids): """ 设置bids进redis @param bdis 需要设置的bids,列表类型 @return True """ # 设置bids进redis redis_store.set('bids', json.dumps(bids)) # 30天过期 redis_store.expire('bids', 60 * 60 * 24 * 30) return True
def post(self): parser = reqparse.RequestParser() parser.add_argument('username', type=str, required=True) parser.add_argument('password', type=str, required=True) parser.add_argument('project_id', type=str, required=True) args = parser.parse_args() username = args['username'] password = args['password'] project_id = args['project_id'] os_admin = os.getenv('ADMIN_USER') os_password = os.getenv("ADMIN_PASSWORD") if username == os_admin and os_password==password: data_user = db.get_by_id("userdata", "project_id", project_id) if not data_user: return response(200, message= "Project ID Not Found") stored_data = { 'username': username, 'project_id': data_user[0]['project_id'], 'user_id': data_user[0]['user_id'], 'timestamp': arrow.now(), 'session': "admin" } random_string = uuid.uuid4() raw_token = '{}{}'.format(random_string, username) access_token = hashlib.sha256(raw_token.encode( 'utf-8')).hexdigest() try: dill_object = dill.dumps(stored_data) redis_store.set(access_token, dill_object) redis_store.expire(access_token,3600) except Exception as e: resp = { "error": str(e) } return response(401, message= resp) else: data = { 'project_id': data_user[0]['project_id'], 'user_id': data_user[0]['user_id'], "token": access_token } return response(200, data= data) else: return response(401, message= "Not Found")
def login(): try: ip_addr = request.headers['X-real-ip'] except: ip_addr = request.remote_addr form = LoginForm() if form.validate_on_submit(): form_data = form.data user = form.get_user() if user is None: flash('用户不存在') return redirect(url_for('auth.login')) if user.status == 0: flash('该账户已经被限制登录') return redirect(url_for('auth.login')) if not user.check_password(form_data['password']): flash('密码错误,请重试!') redis_store.incr('{}'.format(ip_addr), 1) redis_store.expire('{}'.format(ip_addr), 3600) return redirect(url_for('auth.login')) if 'code_text' in session and form_data['validate'].lower( ) != session['code_text'].lower(): flash(u'验证码错误!') return redirect(url_for('auth.login')) login_user(user, remember=form.remember_me.data) user.last_login = datetime.datetime.now() redis_store.delete('{}'.format(ip_addr)) url = requests.get('http://ip.taobao.com/service/getIpInfo.php?ip=%s' % ip_addr) data = url.json() user.ip_addr = ip_addr user.country = data['data']['country'] user.area = data['data']['area'] user.region = data['data']['region'] user.city = data['data']['city'] user.county = data['data']['county'] flash('欢迎回来,%s' % user.username) next_url = request.args.get('next') return redirect(next_url or url_for('public.index')) n_ip = redis_store.get('{}'.format(ip_addr)) pass_error_count = int(n_ip) if n_ip else None if not pass_error_count: try: session.pop('code_text') except: pass return render_template('auth/login.html', title='用户登录', form=form, pass_error_count=pass_error_count)
def post(self): parser = reqparse.RequestParser() parser.add_argument('username', type=str, required=True) parser.add_argument('password', type=str, required=True) args = parser.parse_args() username = args['username'] password = args['password'] try: sess = login_utils.generate_session(username, password, GLOBAL_AUTH_URL, GLOBAL_USER_DOMAIN_NAME) except Exception as e: return str(e) else: user_id = sess.get_user_id() project_id = login_utils.get_project_id(sess) stored_data = { 'username': username, 'user_id': user_id, 'project_id': project_id, 'timestamp': arrow.now(), 'session': sess } random_string = uuid.uuid4() raw_token = '{}{}'.format(random_string, username) access_token = hashlib.sha256( raw_token.encode('utf-8')).hexdigest() try: dill_object = dill.dumps(stored_data) redis_store.set(access_token, dill_object) redis_store.expire(access_token, 3600) except Exception as e: resp = {"error": str(e)} return response(200, message=resp) else: data = { "user_id": user_id, "project_id": project_id, "token": access_token } return response(200, data=data)
def authorized(resp): access_token = resp['access_token'] headers = {'Authorization': 'OAuth ' + access_token} try: req = utils.get_http('https://www.googleapis.com/oauth2/v1/userinfo', None, headers) except Exception: return redirect(url_for('google')) try: dt_db = model.get_by_id("tb_userdata", "email", req['email']) except Exception as e: dt_db = None if not dt_db: data_save = { "sso_id": req['id'], "first_name": req['given_name'], "last_name": req['family_name'], "email": req['email'], "location": "", "picture": req['picture'] } try: model.insert("tb_userdata", data_save) except Exception as e: print(e) expires_in = resp['expires_in'] dill_object = dill.dumps(data_save) redis_store.set(access_token, dill_object) redis_store.expire(access_token, expires_in) else: expires_in = resp['expires_in'] dill_object = dill.dumps(dt_db[0]) redis_store.set(access_token, dill_object) redis_store.expire(access_token, expires_in) data_result = { "Access-Token": access_token, "email": req['email'], "expires": expires_in } return response(200, data=data_result)
def check_token(): ''' 验证token, 如果同一IP认证失败5次,则封禁5分钟 ''' client_ip = request.remote_addr deny_num = redis_store.get(client_ip) deny_num = int(deny_num) if deny_num else 0 if deny_num >= 5: return unauthorized() TOKEN = current_app.config.get('TOKEN') try: key = request.headers.get('token') except: return bad_request() if not key or TOKEN != key: redis_store.incr(client_ip) redis_store.expire(client_ip, 60*5) return forbidden()
def github_authorized(): resp = oauth.github.authorized_response() token = None for i in resp: if i == 'access_token': token = resp[i] req = utils.get_http('https://api.github.com/user?access_token=' + token, None, None) try: dt_db = model.get_by_id("tb_userdata", "email", req['email']) except Exception as e: dt_db = None if not dt_db: data_save = { "sso_id": req['id'], "first_name": req['given_name'], "last_name": req['family_name'], "email": req['email'], "location": "", "picture": req['picture'] } try: model.insert("tb_userdata", data_save) except Exception as e: print(e) dill_object = dill.dumps(data_save) redis_store.set(token, dill_object) redis_store.expire(token, 3600) else: dill_object = dill.dumps(dt_db[0]) redis_store.set(token, dill_object) redis_store.expire(token, 3600) data_result = { "Access-Token": token, "email": req['email'], "expires": 3600 } return response(200, data=data_result)
def get_wx_permission(code): url = config.DevConfig.ACCESS_TOKEN_URL % ( config.DevConfig.appID, config.DevConfig.appSerect, code) try: r = requests.get(url) except Exception as e: logging.warning(u'获取授权失败:%s' % e) return {} else: content = str(r.content, encoding='utf8') content = json.loads(content) access_token = content['access_token'] expires_in = content['expires_in'] refresh_token = content['refresh_token'] openid = content['openid'] scope = content['scope'] redis_store.setnx(code, openid) redis_store.expire(code, 300) data = get_user_data(access_token, openid) url = '/LostAndFound/%s' + '?openid=%s&nicknama=%s&sex=%s' % ( openid, data['nickname'], data['sex']) return url
def set_event(id, event, expire=60 * 60 * 24): """ 使用redis添加event @param id 唯一字符串,这里使用openID @param event 事件类型 @param expire 过期时间,默认24小时 @return key event的key @return None """ key = ":".join(["event", id]) # 使用set,若已存在key,则自动更新为新的event类型 if redis_store.set(key, event): # redis设置成功后,设置过期时间 if redis_store.expire(key, expire): # 过期时间设置成功后,返回key return key else: return None else: return None
def login(): try: res = request.get_json() username = res.get('username') password = res.get('password') Logging.logger.info('request_args:{0}'.format(res)) if not all([username, password]): return jsonify(errno=-1, errmsg='请输入用户名和密码') try: access_counts = redis_store.get('access_' + username) Logging.logger.info('登录错误次数: %s' % access_counts) except Exception as e: Logging.logger.error('errmsg:{0}'.format(e)) return jsonify(errno=-1, errmsg='查询redis失败') # 错误次数不为空 and 错误次数超过了最大值 if access_counts is not None and int(access_counts) >= 5: waiting_time = redis_store.ttl('access_' + username) return jsonify(errno=-1, errmsg='请求错误已超过最大次数,还有%s秒可重新登录' % waiting_time) user = Admin.query.filter_by(username=username).first() if user: if user.status == 0: return jsonify(errno=-1, errmsg='该账号已被停用,请联系管理员') res = hashlib.md5() res.update(password.encode('utf-8')) password = res.hexdigest() if password == user.password: token = user.generate_active_token() user.token = token user.is_login = 1 # 权限状态更新 if user.auth_status == 1: user.auth_status = 0 db.session.add(user) db.session.commit() try: redis_store.delete('access_' + username) except Exception as e: Logging.logger.error('errmsg:{0}'.format(e)) session['user_id'] = user.id session['user_name'] = user.username session['token'] = token data = { "user_id": user.id, "username": username, "token": token, "is_admin": user.is_admin, "status": user.status, "auth_status": user.auth_status } Logging.logger.info('管理员:{0} 登陆成功'.format(username)) return jsonify(errno=0, errmsg="登录成功", data=data) else: # 累加错误次数, 并设置时间 try: # incr:累加错误次数 redis_store.incr('access_' + username) # expire: 第一个参数 key, 第二个参数 过期时间10分钟 redis_store.expire('access_' + username, 600) except Exception as e: Logging.logger.error('errmsg:{0}'.format(e)) return jsonify(errno=-1, errmsg='用户名或密码错误') else: return jsonify(errno=-1, errmsg='用户名不存在') except Exception as e: Logging.logger.error('errmsg:{0}'.format(e)) return jsonify(errno=-1, errmsg='网络异常')
def post(self): """POST /token?code=xxx&redirect_uri=xxx Get token from /sso-v2 and store it into redis. :arg: code: get from sso-v2 redirect_uri: link to redirect :return: For example: {"access_token": xxx} """ # TODO: while redirect_uri and code are missing, return error message. args = login_post_parser.parse_args() code = args['code'] redirect_uri = args['redirect_uri'] if code is None or redirect_uri is None: return {'message': 'params missing'} token_response = requests.post('http://127.0.0.1/sso-v2/api/', data={ 'service': 'App.Oauth.GetAccessToken', 'appid': '12345678', 'appsecret': '12345678', 'code': code }) response_data = token_response.json()['data'] access_token = response_data['access_token'] expires_in = response_data['expires_in'] # get user_id by access_token user_response = requests.post('http://127.0.0.1/sso-v2/api/', data={ 'service': 'App.Oauth.GetUserInfo', 'access_token': access_token, 'types': 'id,name,username,stu_num' }) response_data = user_response.json()['data'] user_id = response_data['id'] name = response_data['name'] username = response_data['username'] stu_num = response_data['stu_num'] user = User.query.filter_by(id=user_id).first() if user is None: new_user = User( id=user_id, username=username, name=name, stu_num=stu_num, role='student', ) db.session.add(new_user) db.session.commit() redis_store.set(access_token, user_id) redis_store.expire(access_token, expires_in) return {'access_token': access_token, 'redirect_uri': redirect_uri}
def wrapper(*args, **kwargs): args_data = [data for data in args] #args_data = ['origin','faculty','page','force_reload'] ''' 若是获取LIST,参数为 origin,faculty,page,force_reload 若是获取DETAIL,参数为 url,request_type ''' if storage_type == 'list': # 缓存新闻列表 name = args_data[0] # origin if name in ['xy', 'jw']: # 将xy,jw与xb区分,方便进行缓存 key = args_data[2] # page else: key = "%s_%s" % (args_data[1], args_data[2]) # faculty_page data = redis_store.hget(name, key) if args_data[3]: data = func(*args, **kwargs) redis_store.hset(name, key, str(data)) redis_store.expire(name, 2592000) # 缓存过期时间为30天 elif data: data = ast.literal_eval(bytes.decode(data)) redis_store.expire(name, 2592000) return data else: return {} ''' else: data = func(*args, **kwargs) redis_store.hset(name, key, str(data)) redis_store.expire(name, 2592000) # 缓存过期时间为30天 ''' elif storage_type == 'detail': # 缓存新闻详细 url = args[0] list_length = len(args) # url result_1 = re.search('http://(.*?)/', url) # 用于判断是是否是教务处新闻详细 if result_1.group(1) == 'www.gdust.cn': result_2 = re.search('(\d{8})\/(\d{1,4})', url) kw = result_2.group(1) + result_2.group(2) else: kw = re.search('\&id\=(\d{1,3})', url).group(1) data = redis_store.get(kw) if args[1]: data = func(*args, **kwargs) redis_store.set(kw, str(data)) redis_store.expire(kw, 2592000) elif data: data = ast.literal_eval(bytes.decode(data)) redis_store.expire(kw, 2592000) return data else: return {} ''' else: data = func(*args, **kwargs) redis_store.set(kw, str(data)) redis_store.expire(kw, 2592000) ''' return data
def login(): """ 用户登录 用户名、 密码 :return: """ #index_url = url_for('.index', _external=True) #if session.get('id'): # return redirect(index_url) #if request.method == 'GET': # return render_template('login.html') # 获取用户传输数据 request_data = request.json username = request_data.get('username') password = request_data.get('password') if not all([username, password]): #return render_template('login.html', message='缺少必要参数') return jsonify(params_error(message='缺少必要参数')) # 获取用户登录IP user_ip = request.remote_addr try: access_nums = redis_store.get('access_num_%s' % user_ip) except Exception as e: current_app.logger.error(e) else: if access_nums and int(access_nums) >= 5: #return render_template('login.html', message='错误次数过多,请稍后重试') return jsonify(unauth_error(message='错误次数过多,请稍后重试')) # 从数据库查询用户对象 try: user_obj = User.query.filter_by(username=username).first() except Exception as e: current_app.logger.error(e) #return render_template('login.html', message='获取用户信息失败') return jsonify(server_error(message='获取用户信息失败')) # 取出用户密码与数据库密码对比 if not user_obj or not user_obj.check_password(password): # 如果用户不存在或者用户密码不正确,返回错误消息,并记录错误次数 try: # redis的incr可以对字符串类型数据进行加1操作,如果数据开始不存在,则默认设置为1 redis_store.incr('access_num_%s' % user_ip) redis_store.expire('access_num_%s' % user_ip, 600) # 数据保存600秒 except Exception as e: current_app.logger.error(e) #return render_template('login.html', message='用户名或密码错误') return jsonify(unauth_error(message='用户名或密码错误')) # 登录成功 session['username'] = username session['nickname'] = user_obj.nickname session['id'] = user_obj.id # 更改用户在线状态 user_obj.state = 1 try: db.session.commit() except Exception as e: current_app.logger.error(e) #return render_template('login.html', message='登录异常') return jsonify(server_error('登录异常')) #return redirect(index_url) return jsonify(success(data=user_obj.to_dict(), message='用户登录成功'))