def put(self, *args, **kwargs): if not self.is_superuser: return self.write(dict(code=-1, msg='不是超级管理员,没有权限')) data = json.loads(self.request.body.decode("utf-8")) user_list = data.get('user_list', None) if len(user_list) != 1: return self.write(dict(code=-2, msg='一次只能选择一个用户,且不能为空')) user_id = user_list[0] with DBContext('r') as session: user_info = session.query(Users).filter( Users.user_id == user_id).first() ### 生成token if user_info.superuser == '0': is_superuser = True else: is_superuser = False token_info = dict(user_id=user_id, username=user_info.username, nickname=user_info.nickname, is_superuser=is_superuser, exp_time=1100) auth_token = AuthToken() auth_key = auth_token.encode_auth_token_v2(**token_info) if isinstance(auth_key, bytes): auth_key = auth_key.decode() redis_conn = cache_conn() configs_init('all') config_info = redis_conn.hgetall(const.APP_SETTINGS) config_info = convert(config_info) obj = SendMail( mail_host=config_info.get(const.EMAIL_HOST), mail_port=config_info.get(const.EMAIL_PORT), mail_user=config_info.get(const.EMAIL_HOST_USER), mail_password=config_info.get(const.EMAIL_HOST_PASSWORD), mail_ssl=True if config_info.get(const.EMAIL_USE_SSL) == '1' else False, mail_tls=True if config_info.get(const.EMAIL_USE_TLS) == '1' else False) with DBContext('w', None, True) as session: mail_to = session.query(Users.email).filter( Users.user_id == self.get_current_id()).first() if mail_to[0] == user_info.email: obj.send_mail(mail_to[0], '令牌,有效期三年', auth_key, subtype='plain') else: obj.send_mail(mail_to[0], '令牌,有效期三年', auth_key, subtype='plain') obj.send_mail(user_info.email, '令牌,有效期三年', auth_key, subtype='plain') return self.write(dict(code=0, msg='Token已经发送到邮箱', data=auth_key))
def prepare(self): # 验证客户端CSRF,如请求为GET,则不验证,否则验证。最后将写入新的key cache = get_cache() if self.request.method != 'GET': csrf_key = self.get_cookie('csrf_key') pipeline = cache.get_pipeline() result = cache.get(csrf_key, private=False, pipeline=pipeline) cache.delete(csrf_key, private=False, pipeline=pipeline) if result != '1': raise HTTPError(400, 'csrf error') cache.set(self.new_csrf_key, 1, expire=1800, private=False) self.set_cookie('csrf_key', self.new_csrf_key) ### 登陆验证 auth_key = self.get_cookie('auth_key', None) if not auth_key: # 没登录,就让跳到登陆页面 raise HTTPError(401, 'auth failed 1') else: auth_token = AuthToken() user_info = auth_token.decode_auth_token(auth_key) self.user_id = user_info.get('user_id', None) self.username = user_info.get('username', None) self.nickname = user_info.get('nickname', None) self.is_super = user_info.get('is_superuser', False) if not self.user_id: raise HTTPError(401, 'auth failed 2') else: self.user_id = str(self.user_id) self.set_secure_cookie("user_id", self.user_id) self.set_secure_cookie("nickname", self.nickname) self.set_secure_cookie("username", self.username) self.is_superuser = self.is_super ## 此处为示例, 如果通过API给个鉴权,则注释 ### 如果不是超级管理员,开始鉴权 # my_verify = MyVerify(self.user_id) # if self.is_super: # # 没权限,就让跳到权限页面 0代表有权限,1代表没权限 # if not my_verify.get_verify(self.request.method, self.request.uri): # '''如果没有权限,就刷新一次权限''' # my_verify.write_verify() # # if not my_verify.get_verify(self.request.method, self.request.uri): # raise HTTPError(403, 'request forbidden!') ### 写入日志 改为网关收集
def prepare(self): # 验证客户端CSRF,如请求为GET,则不验证,否则验证。最后将写入新的key cache = get_cache() if self.request.method not in ("GET", "HEAD", "OPTIONS"): csrf_key = self.get_cookie('csrf_key') pipeline = cache.get_pipeline() result = cache.get(csrf_key, private=False, pipeline=pipeline) cache.delete(csrf_key, private=False, pipeline=pipeline) if result != '1': raise HTTPError(402, 'csrf error') cache.set(self.new_csrf_key, 1, expire=1800, private=False) self.set_cookie('csrf_key', self.new_csrf_key) # 登陆验证 auth_key = self.get_cookie('auth_key', None) if not auth_key: if Authentication_KEY in self.request.headers.keys(): try: auth_key = self.request.headers[Authentication_KEY].split()[1] except: print("不是 JWT-token 格式") if not auth_key: url_auth_key = self.get_argument('auth_key', default=None, strip=True) if url_auth_key: auth_key = bytes(url_auth_key, encoding='utf-8') if not auth_key: raise HTTPError(401, '用户认证失败') user_info = AuthToken().decode_auth_token(auth_key) self.user = user_info
def prepare(self): # 验证客户端CSRF,如请求为GET,则不验证,否则验证。最后将写入新的key cache = get_cache() if self.request.method != 'GET': csrf_key = self.get_cookie('csrf_key') pipeline = cache.get_pipeline() result = cache.get(csrf_key, private=False, pipeline=pipeline) cache.delete(csrf_key, private=False, pipeline=pipeline) if result != '1': raise HTTPError(402, 'csrf error') cache.set(self.new_csrf_key, 1, expire=1800, private=False) self.set_cookie('csrf_key', self.new_csrf_key) ### 登陆验证 auth_key = self.get_cookie('auth_key', None) if not auth_key: # 没登录,就让跳到登陆页面 raise HTTPError(401, 'auth failed 1') else: auth_token = AuthToken() user_info = auth_token.decode_auth_token(auth_key) self.user_id = user_info.get('user_id', None) self.username = user_info.get('username', None) self.nickname = user_info.get('nickname', None) self.email = user_info.get('email', None) self.is_super = user_info.get('is_superuser', False) if not self.user_id: raise HTTPError(401, 'auth failed 2') else: self.user_id = str(self.user_id) self.set_secure_cookie("user_id", self.user_id) self.set_secure_cookie("nickname", self.nickname) self.set_secure_cookie("username", self.username) self.set_secure_cookie("email", str(self.email)) self.is_superuser = self.is_super
def codo_login(self): ### 登陆验证 auth_key = self.get_cookie('auth_key', None) if not auth_key: url_auth_key = self.get_argument('auth_key', default=None, strip=True) if url_auth_key: auth_key = bytes(url_auth_key, encoding='utf-8') if not auth_key: raise HTTPError(401, 'auth failed') if self.token_verify: auth_token = AuthToken() user_info = auth_token.decode_auth_token(auth_key) else: user_info = jwt.decode(auth_key, options={ "verify_signature": False }).get('data') if not user_info: raise HTTPError(401, 'auth failed') self.user_id = user_info.get('user_id', None) self.username = user_info.get('username', None) self.nickname = user_info.get('nickname', None) self.email = user_info.get('email', None) self.is_super = user_info.get('is_superuser', False) if not self.user_id: raise HTTPError(401, 'auth failed') self.user_id = str(self.user_id) self.set_secure_cookie("user_id", self.user_id) self.set_secure_cookie("nickname", self.nickname) self.set_secure_cookie("username", self.username) self.set_secure_cookie("email", str(self.email)) self.is_superuser = self.is_super
def post(self, *args, **kwargs): data = json.loads(self.request.body.decode("utf-8")) username = data.get('username', None) password = data.get('password', None) dynamic = data.get('dynamic', None) if not username or not password: return self.write(dict(code=-1, msg='账号密码不能为空')) redis_conn = cache_conn() configs_init('all') if is_mail(username): login_mail = redis_conn.hget(const.APP_SETTINGS, const.EMAILLOGIN_DOMAIN) if login_mail: if is_mail(username, login_mail.decode('utf-8')): email = username username = email.split("@")[0] email_server = redis_conn.hget(const.APP_SETTINGS, const.EMAILLOGIN_SERVER).decode('utf-8') if not email_server: return self.write(dict(code=-9, msg='请配置邮箱服务的SMTP服务地址')) if not mail_login(email, password, email_server): return self.write(dict(code=-2, msg='邮箱登陆认证失败')) with DBContext('r') as session: user_info = session.query(Users).filter(Users.email == email, Users.username == username, Users.status != '10').first() if not user_info: return self.write(dict(code=-3, msg='邮箱认证通过,请根据邮箱完善用户信息', username=username, email=email)) else: with DBContext('r') as session: user_info = session.query(Users).filter(Users.username == username, Users.password == gen_md5(password), Users.status != '10').first() if not user_info: # redis_conn = cache_conn() # configs_init('all') ldap_login = redis_conn.hget(const.APP_SETTINGS, const.LDAP_ENABLE) ldap_login = convert(ldap_login) if ldap_login != '1': return self.write(dict(code=-4, msg='账号密码错误')) ### 如果开启了LDAP认证 则进行LDAP认证 else: #### config_info = redis_conn.hgetall(const.APP_SETTINGS) config_info = convert(config_info) ldap_ssl = True if config_info.get(const.LDAP_USE_SSL) == '1' else False obj = LdapApi(config_info.get(const.LDAP_SERVER_HOST), config_info.get(const.LDAP_ADMIN_DN), config_info.get(const.LDAP_ADMIN_PASSWORD), int(config_info.get(const.LDAP_SERVER_PORT, 389)), ldap_ssl) ldap_pass_info = obj.ldap_auth(username, password, config_info.get(const.LDAP_SEARCH_BASE), config_info.get(const.LDAP_SEARCH_FILTER)) if ldap_pass_info[0]: with DBContext('r') as session: if not ldap_pass_info[2]: return self.write(dict(code=-11, msg='LDAP认证成功,但是没有找到用户邮箱,请完善!')) else: user_info = session.query(Users).filter(Users.email == ldap_pass_info[2], Users.username == username, Users.status != '10').first() if not user_info: return self.write(dict(code=-3, msg='LDAP认证通过,完善用户信息', username=ldap_pass_info[1], email=ldap_pass_info[2])) else: return self.write(dict(code=-4, msg='账号密码错误')) if 'user_info' not in dir(): return self.write(dict(code=-4, msg='账号异常')) if user_info.status != '0': return self.write(dict(code=-4, msg='账号被禁用')) is_superuser = True if user_info.superuser == '0' else False ### 如果被标记为必须动态验证切没有输入动态密钥,则跳转到二维码添加密钥的地方 ### 默认为 True, False 则全局禁用MFA mfa_global = False if convert(redis_conn.hget(const.APP_SETTINGS, const.MFA_GLOBAL)) == '1' else True if mfa_global and user_info.google_key: if not dynamic: ### 第一次不带MFA的认证 return self.write(dict(code=1, msg='跳转二次认证')) else: ### 二次认证 t_otp = pyotp.TOTP(user_info.google_key) if t_otp.now() != str(dynamic): return self.write(dict(code=-5, msg='MFA错误')) user_id = str(user_info.user_id) ### 生成token 并写入cookie token_exp_hours = redis_conn.hget(const.APP_SETTINGS, const.TOKEN_EXP_TIME) if token_exp_hours and convert(token_exp_hours): token_info = dict(user_id=user_id, username=user_info.username, nickname=user_info.nickname, email=user_info.email, is_superuser=is_superuser, exp_hours=token_exp_hours) else: token_info = dict(user_id=user_id, username=user_info.username, nickname=user_info.nickname, email=user_info.email, is_superuser=is_superuser) auth_token = AuthToken() auth_key = auth_token.encode_auth_token_v2(**token_info) login_ip_list = self.request.headers.get("X-Forwarded-For") if login_ip_list: login_ip = login_ip_list.split(",")[0] with DBContext('w', None, True) as session: session.query(Users).filter(Users.user_id == user_id).update({Users.last_ip: login_ip}) session.commit() self.set_secure_cookie("nickname", user_info.nickname) self.set_secure_cookie("username", user_info.username) self.set_secure_cookie("user_id", str(user_info.user_id)) self.set_cookie('auth_key', auth_key, expires_days=1) ### 后端权限写入缓存 my_verify = MyVerify(user_id, is_superuser) my_verify.write_verify() ### 前端权限写入缓存 # get_user_rules(user_id, is_superuser) return self.write(dict(code=0, auth_key=auth_key.decode(), username=user_info.username, nickname=user_info.nickname, msg='登录成功'))
def post(self, *args, **kwargs): data = json.loads(self.request.body.decode("utf-8")) username = data.get('username', None) password = data.get('password', None) dynamic = data.get('dynamic', None) next_url = data.get('next_url', None) if not username or not password: return self.write(dict(code=-1, msg='账号密码不能为空')) if is_mail(username): redis_conn = cache_conn() configs_init('all') login_mail = redis_conn.hget(const.APP_SETTINGS, const.EMAILLOGIN_DOMAIN) if login_mail: if is_mail(username, login_mail.decode('utf-8')): email = username username = email.split("@")[0] email_server = redis_conn.hget( const.APP_SETTINGS, const.EMAILLOGIN_SERVER).decode('utf-8') if not email_server: return self.write(dict(code=-9, msg='请配置邮箱服务的SMTP服务地址')) if not mail_login(email, password, email_server): return self.write(dict(code=-2, msg='邮箱登陆认证失败')) with DBContext('r') as session: user_info = session.query(Users).filter( Users.email == email, Users.username == username, Users.status != '10').first() if not user_info: return self.write( dict(code=-3, msg='邮箱认证通过,请根据邮箱完善用户信息', email=email)) else: with DBContext('r') as session: user_info = session.query(Users).filter( Users.username == username, Users.password == gen_md5(password), Users.status != '10').first() if not user_info: return self.write(dict(code=-4, msg='账号密码错误')) if user_info.status != '0': return self.write(dict(code=-4, msg='账号被禁用')) if user_info.superuser == '0': is_superuser = True else: is_superuser = False ### 如果被标记为必须动态验证切没有输入动态密钥,则跳转到二维码添加密钥的地方 if user_info.google_key: totp = pyotp.TOTP(user_info.google_key) if dynamic: if totp.now() != str(dynamic): return self.write(dict(code=-5, msg='MFA错误')) else: return self.write(dict(code=-8, msg='请输入MFA')) user_id = str(user_info.user_id) ### 生成token 并写入cookie token_info = dict(user_id=user_id, username=user_info.username, nickname=user_info.nickname, is_superuser=is_superuser) auth_token = AuthToken() auth_key = auth_token.encode_auth_token(**token_info) login_ip_list = self.request.headers.get("X-Forwarded-For") if login_ip_list: login_ip = login_ip_list.split(",")[0] with DBContext('w', None, True) as session: session.query(Users).filter(Users.user_id == user_id).update( {Users.last_ip: login_ip}) self.set_secure_cookie("nickname", user_info.nickname) self.set_secure_cookie("username", user_info.username) self.set_secure_cookie("user_id", str(user_info.user_id)) self.set_cookie('auth_key', auth_key, expires_days=1) ### 后端权限写入缓存 my_verify = MyVerify(user_id) my_verify.write_verify() ### 前端权限写入缓存 get_user_rules(user_id) return self.write( dict(code=0, auth_key=auth_key.decode(encoding="utf-8"), username=user_info.username, nickname=user_info.nickname, next_url=next_url, msg='登录成功'))