Example #1
0
def userprofile():
    res = dict(msg=None, code=1)
    if request.method == "GET":
        getBind = True if request.args.get("getBind") in ("true", "True", True) else False
        res = g.api.userprofile.getUserProfile(g.uid, getBind)
    elif request.method == "POST":
        Action = request.args.get("Action")
        if Action == "bindLauth":
            account = request.form.get("account")
            vcode = request.form.get("vcode")
            password = request.form.get("password")
            auth = Authentication()
            res = auth.bindLauth(uid=g.uid, account=account, vcode=vcode, password=password)
            if res["success"] == True and res["show_realname_tip"] == True:
                res['set_realname'] = g.api.userprofile.updateUserRealname(g.uid)
    elif request.method == "PUT":
        """修改个人资料,包含:基本资料、密码、头像、社交账号绑定"""
        Action = request.args.get("Action")
        if Action == "profile":
            data = {k: v for k, v in request.form.iteritems() if k in ("nick_name", "domain_name", "birthday", "location", "gender", "signature")}
            res = g.api.userprofile.updateUserProfile(uid=g.uid, **data)
            if res["code"] == 0:
                # 同步基本资料
                g.api.usersso.clientsConSync(g.api.userapp.getUserApp, g.uid, dict(CallbackType="user_profile", CallbackData=data))
        elif Action == "password":
            nowpass = request.form.get("nowpass")
            newpass = request.form.get("newpass")
            repass = request.form.get("repass")
            res = g.api.userprofile.updateUserPassword(uid=g.uid, nowpass=nowpass, newpass=newpass, repass=repass)
    logger.info(res)
    return jsonify(dfr(res))
Example #2
0
def signUp():
    if request.method == 'POST':
        if vaptcha.validate:
            account = request.form.get("account")
            vcode = request.form.get("vcode")
            password = request.form.get("password")
            repassword = request.form.get("repassword")
            auth = Authentication(g.mysql, g.redis)
            try:
                res = auth.signUp(account=account,
                                  vcode=vcode,
                                  password=password,
                                  repassword=repassword,
                                  register_ip=g.ip)
            except Exception, e:
                logger.error(e, exc_info=True)
                flash(u"系统异常,请稍后再试")
            else:
                res = dfr(res)
                if res["success"]:
                    # 写登陆日志
                    return redirect(url_for('.signIn'))
                else:
                    flash(res["msg"])
        else:
            flash(u"人机验证失败")
        return redirect(url_for('.signUp'))
Example #3
0
def signUp():
    if request.method == 'POST':
        res = dict(msg=None, code=1, nextUrl=url_for('.signUp'))
        if vaptcha.validate:
            account = request.form.get("account")
            vcode = request.form.get("vcode")
            password = request.form.get("password")
            repassword = request.form.get("repassword")
            auth = Authentication(g.mysql, g.redis)
            result = auth.signUp(account=account,
                                 vcode=vcode,
                                 password=password,
                                 repassword=repassword,
                                 register_ip=g.ip)
            #注册欢迎消息
            FastPushMessage(
                result, "欢迎您的加入!%s使用中有任何问题,都可以反馈哦。" %
                ("" if email_check(account) else "您使用手机注册,已经完成实名认证!", ))
            if result["success"]:
                res.update(code=0, nextUrl=url_for('.signIn'))
            else:
                res.update(msg=result["msg"])
        else:
            res.update(msg="Man-machine verification failed")
        print res
        return jsonify(dfr(res))
    return render_template("auth/signUp.html", vaptcha=vaptcha.getChallenge)
Example #4
0
def OAuthDirectLogin():
    """OAuth2直接登录(首选)"""
    if request.method == 'POST':
        openid = request.form.get("openid")
        if openid:
            auth = Authentication(g.mysql, g.redis)
            # 直接注册新账号并设置登录态
            ip = request.headers.get('X-Real-Ip', request.remote_addr)
            res = auth.oauth2_signUp(openid, ip)
            res = dfr(res)
            if res["success"]:
                # 记录登录日志
                auth.brush_loginlog(
                    res,
                    login_ip=ip,
                    user_agent=request.headers.get("User-Agent"))
                # 登录成功,设置cookie
                sessionId = set_cookie(uid=res["uid"])
                response = make_response(redirect(url_for(".index")))
                # 设置cookie根据浏览器周期过期,当无https时去除`secure=True`
                secure = False if request.url_root.split(
                    "://")[0] == "http" else True
                response.set_cookie(key="sessionId",
                                    value=sessionId,
                                    max_age=None,
                                    httponly=True,
                                    secure=secure)
                return response
            else:
                flash(res["msg"])
            return redirect(url_for('.index'))
        else:
            return redirect(url_for(".index"))
Example #5
0
def signUp():
    if request.method == 'POST':
        sceneid = request.args.get("sceneid") or "02"
        token = request.form.get("token")
        challenge = request.form.get("challenge")
        if token and challenge and vaptcha.validate(challenge, token, sceneid):
            account = request.form.get("account")
            vcode = request.form.get("vcode")
            password = request.form.get("password")
            repassword = request.form.get("repassword")
            register_ip = request.headers.get('X-Real-Ip', request.remote_addr)
            auth = Authentication(g.mysql, g.redis)
            try:
                res = auth.signUp(account=account,
                                  vcode=vcode,
                                  password=password,
                                  repassword=repassword,
                                  register_ip=register_ip)
            except Exception, e:
                logger.error(e, exc_info=True)
                flash(u"系统异常,请稍后再试")
            else:
                res = dfr(res)
                if res["success"]:
                    # 写登陆日志
                    return redirect(url_for('.signIn'))
                else:
                    flash(res["msg"])
        else:
            flash(u"人机验证失败")
        return redirect(url_for('.signUp'))
Example #6
0
def OAuthDirectLogin():
    """OAuth2直接登录(首选)"""
    if request.method == 'POST':
        sso = request.args.get("sso") or None
        logger.debug("OAuthDirectLogin, sso type: {}, content: {}".format(
            type(sso), sso))
        openid = request.form.get("openid")
        if openid:
            auth = Authentication(g.mysql, g.redis)
            # 直接注册新账号并设置登录态
            res = auth.oauth2_signUp(openid, g.ip)
            res = dfr(res)
            if res["success"]:
                # 记录登录日志
                auth.brush_loginlog(
                    res,
                    login_ip=g.ip,
                    user_agent=request.headers.get("User-Agent"))
                sso_isOk, sso_returnUrl, sso_appName = checkGet_ssoRequest(sso)
                sessionId, returnUrl = checkSet_ssoTicketSid(
                    sso_isOk, sso_returnUrl, sso_appName, res["uid"],
                    url_for("front.userset", _anchor="bind"))
                logger.debug(
                    "OAuthDirectLogin post returnUrl: {}".format(returnUrl))
                return set_loginstate(sessionId, returnUrl)
            else:
                flash(res["msg"])
                return redirect(
                    url_for("front.OAuthGuide", openid=openid, sso=sso))
        else:
            return redirect(g.redirect_uri)
Example #7
0
def userlogin():
    if request.method == 'POST':
        res = dict(code=1)
        auth = Authentication(g.mysql, g.redis)
        result = auth.signIn(
            account=request.form.get("account"),
            password=request.form.get("password")
        )
        if result["success"]:
            uid = result["uid"]
            # 记录登录日志
            auth.brush_loginlog(result, login_ip=g.ip, user_agent=g.agent)
            fields = request.form.get("fields") or "is_admin,avatar,nick_name"
            fields = [i for i in comma_pat.split(fields) if i]
            fields = set(fields)
            fields.update(["avatar", "nick_name"])
            fields = list(fields)
            infores = g.api.userprofile.getUserProfile(uid)
            data = {}
            if infores["code"] == 0:
                data = infores["data"]
            data.update(token=set_sessionId(uid, 7200))
            res.update(code=0, data={k: data[k] for k in fields if k in data})
        else:
            res.update(msg=result["msg"])
        return jsonify(dfr(res))
Example #8
0
def authorized():
    """ 授权回调路由
    此路由地址:/oauth2/gitee/authorized
    """
    # 加密的sso参数值
    sso = request.args.get("sso") or None
    # 换取access_token
    resp = gitee.authorized_response()
    print resp
    if resp and isinstance(resp, dict) and "access_token" in resp:
        # 根据access_token获取用户基本信息
        user = gitee.get_userinfo(resp["access_token"])
        if not "id" in user:
            flash(user.get("status", "Gitee error"))
            return redirect(g.redirect_uri)
        # 处理第三方登录逻辑
        auth = Authentication(g.mysql, g.redis)
        # 第三方账号登录入口`oauth2_go`
        goinfo = auth.oauth2_go(name=name,
                                signin=g.signin,
                                tokeninfo=resp,
                                userinfo=dict(openid=user["id"],
                                              nick_name=user["name"],
                                              gender=2,
                                              avatar=user["avatar_url"],
                                              domain_name=user["login"],
                                              signature=user["bio"]),
                                uid=g.uid)
        goinfo = dfr(goinfo)
        if goinfo["pageAction"] == "goto_signIn":
            """ 未登录流程->已经绑定过账号,需要设置登录态 """
            uid = goinfo["goto_signIn_data"]["guid"]
            # 记录登录日志
            auth.brush_loginlog(dict(identity_type=oauth2_name2type(name),
                                     uid=uid,
                                     success=True),
                                login_ip=g.ip,
                                user_agent=request.headers.get("User-Agent"))
            # 设置登录态
            return gitee.goto_signIn(uid=uid, sso=sso)
        elif goinfo["pageAction"] == "goto_signUp":
            """ 未登录流程->执行注册绑定功能 """
            return gitee.goto_signUp(
                openid=goinfo["goto_signUp_data"]["openid"], sso=sso)
        else:
            # 已登录流程->正在绑定第三方账号:反馈绑定结果
            if goinfo["success"]:
                # 绑定成功,返回原页面
                flash(u"已绑定")
            else:
                # 绑定失败,返回原页面
                flash(goinfo["msg"])
            # 跳回绑定设置页面
            return redirect(url_for("front.userset", _anchor="bind"))
    else:
        flash(u'Access denied: reason=%s error=%s' %
              (resp.get('error'), resp.get('error_description')))
    return redirect(g.redirect_uri)
Example #9
0
def fgp():
    # 忘记密码页-重置密码
    res = dict(msg=None, success=False)
    if request.method == "POST":
        vcode = request.form.get("vcode")
        account = request.form.get("account")
        password = request.form.get("password")
        if vaptcha.validate:
            auth = Authentication()
            res = auth.forgot(account=account, vcode=vcode, password=password)
        else:
            res.update(msg="Man-machine verification failed")
    return jsonify(dfr(res))
Example #10
0
def authorized():
    """ 授权回调路由
    此路由地址:/oauth2/qq/authorized
    """
    # 加密的sso参数值
    sso = request.args.get("sso") or None
    # 换取access_token
    resp = qq.authorized_response()
    if "callback" in resp:
        resp = json.loads(resp[10:-3])
    else:
        resp = qq.url_code(resp)
    if resp and isinstance(resp, dict) and "access_token" in resp:
        # 获取用户唯一标识
        openid = json.loads(qq.get_openid(resp["access_token"])[10:-3]).get("openid")
        # 根据access_token获取用户基本信息
        user = qq.get_userinfo(resp["access_token"], openid=openid, oauth_consumer_key=PLUGINS[name]["APP_ID"])
        if int(user.get("ret", 0)) < 0:
            flash(user.get("msg"))
            return redirect(g.redirect_uri)
        # 处理第三方登录逻辑
        auth = Authentication(g.mysql, g.redis)
        # 第三方账号登录入口`oauth2_go`
        goinfo = auth.oauth2_go(name=name, signin=g.signin, tokeninfo=resp, userinfo=dict(openid=openid, nick_name=user["nickname"], gender=oauth2_genderconverter(user["gender"]), avatar=user["figureurl_qq_2"] or user["figureurl_qq_1"], location="%s %s" %(user.get("province"), user.get("city"))), uid=g.uid)
        goinfo = dfr(goinfo)
        if goinfo["pageAction"] == "goto_signIn":
            """ 未登录流程->已经绑定过账号,需要设置登录态 """
            uid = goinfo["goto_signIn_data"]["guid"]
            # 记录登录日志
            auth.brush_loginlog(dict(identity_type=oauth2_name2type(name), uid=uid, success=True), login_ip=g.ip, user_agent=request.headers.get("User-Agent"))
            # 设置登录态
            return qq.goto_signIn(uid=uid, sso=sso)
        elif goinfo["pageAction"] == "goto_signUp":
            """ 未登录流程->openid没有对应账号,执行注册或绑定功能 """
            return qq.goto_signUp(openid=goinfo["goto_signUp_data"]["openid"], sso=sso)
        else:
            # 已登录流程->正在绑定第三方账号:反馈绑定结果
            if goinfo["success"]:
                # 绑定成功,返回原页面
                flash(u"已绑定")
            else:
                # 绑定失败,返回原页面
                flash(goinfo["msg"])
            # 跳回绑定设置页面
            return redirect(url_for("front.userset", _anchor="bind"))
    else:
        flash(u'Access denied: reason=%s error=%s' % (
            resp.get('error'),
            resp.get('error_description')
        ))
    return redirect(g.redirect_uri)
Example #11
0
def fgp():
    # 忘记密码页-重置密码
    res = dict(msg=None, code=1)
    if request.method == "POST":
        vcode = request.form.get("vcode")
        account = request.form.get("account")
        password = request.form.get("password")
        auth = Authentication(g.mysql, g.redis)
        result = auth.forgot(account=account, vcode=vcode, password=password)
        if result["success"]:
            res.update(code=0, nextUrl=url_for("front.signIn"))
        else:
            res.update(msg=result["msg"])
    return jsonify(dfr(res))
Example #12
0
def unbind():
    # 解绑账号
    identity_name = request.args.get("identity_name")
    if identity_name:
        auth = Authentication(g.mysql, g.redis)
        res = auth.unbind(g.uid, oauth2_name2type(identity_name))
        res = dfr(res)
        if res["code"] == 0:
            flash(u"解绑成功")
        else:
            flash(res["msg"])
    else:
        flash(u"无效参数")
    return redirect(url_for("front.userset", _anchor="bind"))
Example #13
0
def authorized():
    """ 授权回调路由
    此路由地址:/oauth2/coding/authorized
    """
    # 加密的sso参数值
    sso = request.args.get("sso") or None
    # 换取access_token
    resp = coding.authorized_response()
    if resp and isinstance(resp, dict) and "access_token" in resp:
        # 根据access_token获取用户基本信息
        user = coding.get_userinfo(resp["access_token"])
        if user["code"] != 0:
            flash(user["msg"].keys())
            return redirect(g.redirect_uri)
        user = user["data"]
        # 处理第三方登录逻辑
        auth = Authentication(g.mysql, g.redis)
        # 第三方账号登录入口`oauth2_go`
        avatar = "https://coding.net" + user["avatar"] if user["avatar"].startswith("/") else user["avatar"]
        goinfo = auth.oauth2_go(name=name, signin=g.signin, tokeninfo=resp, userinfo=dict(openid=user["id"], nick_name=user["name"], gender=oauth2_genderconverter(user["sex"]), avatar=avatar, domain_name=user["global_key"], signature=user["slogan"], location=user.get("location")), uid=g.uid)
        goinfo = dfr(goinfo)
        if goinfo["pageAction"] == "goto_signIn":
            """ 未登录流程->已经绑定过账号,需要设置登录态 """
            uid = goinfo["goto_signIn_data"]["guid"]
            # 记录登录日志
            auth.brush_loginlog(dict(identity_type=oauth2_name2type(name), uid=uid, success=True), login_ip=g.ip, user_agent=request.headers.get("User-Agent"))
            # 设置登录态
            return coding.goto_signIn(uid=uid, sso=sso)
        elif goinfo["pageAction"] == "goto_signUp":
            """ 未登录流程->执行注册绑定功能 """
            return coding.goto_signUp(openid=goinfo["goto_signUp_data"]["openid"], sso=sso)
        else:
            # 已登录流程->正在绑定第三方账号:反馈绑定结果
            if goinfo["success"]:
                # 绑定成功,返回原页面
                flash(u"已绑定")
            else:
                # 绑定失败,返回原页面
                flash(goinfo["msg"])
            # 跳回绑定设置页面
            return redirect(url_for("front.userset", _anchor="bind"))
    else:
        flash(u'Access denied: reason=%s error=%s' % (
            request.args.get('error'),
            request.args.get('error_description')
        ))
    return redirect(g.redirect_uri)
Example #14
0
def fgp():
    # 忘记密码页-重置密码
    res = dict(msg=None, code=1)
    if request.method == "POST":
        vcode = request.form.get("vcode")
        account = request.form.get("account")
        password = request.form.get("password")
        if vaptcha.validate:
            auth = Authentication()
            result = auth.forgot(account=account, vcode=vcode, password=password)
            if result["success"]:
                res.update(code=0, nextUrl=url_for("front.signIn"))
            else:
                res.update(msg=result["msg"])
        else:
            res.update(msg="Man-machine verification failed")
    return jsonify(dfr(res))
Example #15
0
def OAuthBindAccount():
    """OAuth2绑定已有账号登录"""
    if request.method == 'POST':
        openid = request.form.get("openid")
        sceneid = request.args.get("sceneid") or "03"
        token = request.form.get("token")
        challenge = request.form.get("challenge")
        if token and challenge and vaptcha.validate(challenge, token, sceneid):
            account = request.form.get("account")
            password = request.form.get("password")
            auth = Authentication(g.mysql, g.redis)
            res = auth.oauth2_bindLogin(openid=openid,
                                        account=account,
                                        password=password)
            res = dfr(res)
            if res["success"]:
                # 记录登录日志
                auth.brush_loginlog(
                    res,
                    login_ip=request.headers.get('X-Real-Ip',
                                                 request.remote_addr),
                    user_agent=request.headers.get("User-Agent"))
                # 登录成功,设置cookie
                sessionId = set_cookie(uid=res["uid"])
                response = make_response(redirect(url_for(".index")))
                # 设置cookie根据浏览器周期过期,当无https时去除`secure=True`
                secure = False if request.url_root.split(
                    "://")[0] == "http" else True
                response.set_cookie(key="sessionId",
                                    value=sessionId,
                                    max_age=None,
                                    httponly=True,
                                    secure=secure)
                return response
            else:
                flash(res["msg"])
        else:
            flash(u"人机验证失败")
        return redirect(url_for('.OAuthBindAccount', openid=openid))
    else:
        openid = request.args.get("openid")
        if openid:
            return render_template("auth/OAuthBindAccount.html")
        else:
            redirect(url_for(".index"))
Example #16
0
def authorized():
    """ 授权回调路由
    此路由地址:/oauth2/baidu/authorized
    """
    # 换取access_token
    resp = baidu.authorized_response()
    print "authorized_response:",resp
    if resp and isinstance(resp, dict) and "access_token" in resp:
        # 根据access_token获取用户基本信息
        user = baidu.get_userinfo(resp["access_token"])
        if user.get("error"):
            flash("{} error_description: {}".format(user.get("error"), user.get("error_description")))
            return redirect(url_for("front.index"))
        # 处理第三方登录逻辑
        auth = Authentication(g.mysql, g.redis)
        avatar = "http://tb.himg.baidu.com/sys/portrait/item/" + user["portrait"]
        # 第三方账号登录入口`oauth2_go`
        goinfo = auth.oauth2_go(name=name, signin=g.signin, tokeninfo=resp, userinfo=dict(openid=user["userid"], nick_name=user["username"], gender=user["sex"], avatar=avatar, signature=user["userdetail"], location=user.get("location")), uid=g.uid)
        goinfo = dfr(goinfo)
        if goinfo["pageAction"] == "goto_signIn":
            """ 未登录流程->执行登录 """
            # 记录登录日志
            auth.brush_loginlog(dict(identity_type=oauth2_name2type(name), uid=goinfo["goto_signIn_data"]["guid"], success=True), login_ip=request.headers.get('X-Real-Ip', request.remote_addr), user_agent=request.headers.get("User-Agent"))
            # 设置登录态
            return baidu.goto_signIn(uid=goinfo["goto_signIn_data"]["guid"])
        elif goinfo["pageAction"] == "goto_signUp":
            """ 未登录流程->执行注册绑定功能 """
            return baidu.goto_signUp(openid=goinfo["goto_signUp_data"]["openid"])
        else:
            # 已登录流程->反馈绑定结果
            if goinfo["success"]:
                # 绑定成功,返回原页面
                flash(u"已绑定")
            else:
                # 绑定失败,返回原页面
                flash(goinfo["msg"])
            # 跳回原页面
            return redirect(url_for("front.index"))
    else:
        flash(u'Access denied: reason=%s error=%s' % (
            request.args.get('error'),
            request.args.get('error_description')
        ))
    return redirect(url_for("front.index"))
Example #17
0
def authorized():
    """ 授权回调路由
    此路由地址:/oauth2/github/authorized
    """
    # 换取access_token
    resp = github.authorized_response()
    resp = github.url_code(resp)
    print "authorized_response:",resp
    if resp and isinstance(resp, dict) and "access_token" in resp:
        # 根据access_token获取用户基本信息
        user = github.get_userinfo(resp["access_token"])
        # 处理第三方登录逻辑
        auth = Authentication(g.mysql, g.redis)
        # 第三方账号登录入口`oauth2_go`
        goinfo = auth.oauth2_go(name=name, signin=g.signin, tokeninfo=resp, userinfo=dict(openid=user["id"], nick_name=user["name"], gender=2, avatar=user["avatar_url"], domain_name=user["login"], signature=user["bio"], location=user.get("location")), uid=g.uid)
        goinfo = dfr(goinfo)
        if goinfo["pageAction"] == "goto_signIn":
            """ 未登录流程->执行登录 """
            # 记录登录日志
            auth.brush_loginlog(dict(identity_type=oauth2_name2type(name), uid=goinfo["goto_signIn_data"]["guid"], success=True), login_ip=request.headers.get('X-Real-Ip', request.remote_addr), user_agent=request.headers.get("User-Agent"))
            # 设置登录态
            return github.goto_signIn(uid=goinfo["goto_signIn_data"]["guid"])
        elif goinfo["pageAction"] == "goto_signUp":
            """ 未登录流程->执行注册绑定功能 """
            return github.goto_signUp(openid=goinfo["goto_signUp_data"]["openid"])
        else:
            # 已登录流程->反馈绑定结果
            if goinfo["success"]:
                # 绑定成功,返回原页面
                flash(u"已绑定")
            else:
                # 绑定失败,返回原页面
                flash(goinfo["msg"])
            # 跳回原页面
            return redirect(url_for("front.index"))
    else:
        flash(u'Access denied: reason=%s error=%s' % (
            request.args.get('error'),
            request.args.get('error_description')
        ))
    return redirect(url_for("front.index"))
Example #18
0
def OAuthBindAccount():
    """OAuth2绑定已有账号登录"""
    if request.method == 'POST':
        sso = request.args.get("sso") or None
        logger.debug("OAuthBindAccount, sso type: {}, content: {}".format(
            type(sso), sso))
        openid = request.form.get("openid")
        if vaptcha.validate:
            account = request.form.get("account")
            password = request.form.get("password")
            auth = Authentication(g.mysql, g.redis)
            res = auth.oauth2_bindLogin(openid=openid,
                                        account=account,
                                        password=password)
            res = dfr(res)
            if res["success"]:
                # 记录登录日志
                auth.brush_loginlog(
                    res,
                    login_ip=g.ip,
                    user_agent=request.headers.get("User-Agent"))
                sso_isOk, sso_returnUrl, sso_appName = checkGet_ssoRequest(sso)
                sessionId, returnUrl = checkSet_ssoTicketSid(
                    sso_isOk, sso_returnUrl, sso_appName, res["uid"],
                    url_for("front.userset", _anchor="bind"))
                logger.debug(
                    "OAuthBindAccount post returnUrl: {}".format(returnUrl))
                return set_loginstate(sessionId, returnUrl)
            else:
                flash(res["msg"])
        else:
            flash(u"人机验证失败")
        return redirect(url_for('.OAuthBindAccount', openid=openid, sso=sso))
    else:
        openid = request.args.get("openid")
        if openid:
            return render_template("auth/OAuthBindAccount.html",
                                   vaptcha=vaptcha.getChallenge)
        else:
            return redirect(g.redirect_uri)
Example #19
0
def signIn():
    if request.method == 'POST':
        sceneid = request.args.get("sceneid") or "01"
        token = request.form.get("token")
        challenge = request.form.get("challenge")
        if token and challenge and vaptcha.validate(challenge, token, sceneid):
            account = request.form.get("account")
            password = request.form.get("password")
            login_ip = request.headers.get('X-Real-Ip', request.remote_addr)
            auth = Authentication(g.mysql, g.redis)
            res = auth.signIn(account=account, password=password)
            res = dfr(res)
            if res["success"]:
                # 记录登录日志
                auth.brush_loginlog(
                    res,
                    login_ip=login_ip,
                    user_agent=request.headers.get("User-Agent"))
                # 登录成功,设置cookie
                sessionId = set_cookie(uid=res["uid"])
                response = make_response(redirect(g.redirect_uri))
                # 设置cookie根据浏览器周期过期,当无https时去除`secure=True`
                secure = False if request.url_root.split(
                    "://")[0] == "http" else True
                response.set_cookie(key="sessionId",
                                    value=sessionId,
                                    max_age=None,
                                    httponly=True,
                                    secure=secure)
                return response
            else:
                flash(res["msg"])
        else:
            flash(u"人机验证失败")
        return redirect(url_for('.signIn'))
    return render_template("auth/signIn.html")
Example #20
0
def signIn():
    """ 单点登录流程
        1. Client跳转到Server的登录页,携带参数sso(所需sso信息的加密串),验证并获取应用数据。
        2. 未登录时,GET请求显示登录表单,输入用户名密码或第三方POST登录成功后(一处是signIn post;一处是OAuthDirectLogin post;一处是OAuthBindAccount post),创建全局会话(设置Server登录态)、授权令牌ticket,根据ticket生成sid(全局会话id)写入redis,ReturnUrl组合ticket跳转;
           已登录后,检查是否有sid,没有则创建ticket,ReturnUrl组合ticket跳转。
        3. 校验参数通过后,设置ReturnUrl(从数据库读取)为Client登录地址;校验未通过时ReturnUrl为系统redirect_uri。
        4. Client用ticket到Server校验(通过api方式),通过redis校验cookie是否存在;存在则创建局部会话(设置Client登录态),否则登录失败。
        -- sso加密规则:
            aes_cbc(jwt_encrypt("app_name:app_id.app_secret"))
        -- sso校验流程:
            根据sso参数,验证是否有效,解析参数获取name、id、secret等,并用name获取到对应信息一一校验
        -- 备注:
            第3步,需要signIn、OAuthGuide方面路由设置
            第4步,需要在插件内增加api路由
    """
    # 加密的sso参数值
    sso = request.args.get("sso") or None
    sso_isOk, sso_returnUrl, sso_appName = checkGet_ssoRequest(sso)
    logger.debug("method: {}, sso_isOk: {}, ReturnUrl: {}".format(
        request.method, sso_isOk, sso_returnUrl))
    if g.signin:
        # 已登录后流程
        # 如果没有sid说明是本地登录,需要重置登录态
        if sso_isOk:
            if g.sid:
                # 创建ticket,返回为真即是ticket
                tickets = g.api.usersso.ssoCreateTicket(sid=g.sid,
                                                        agent=g.agent,
                                                        ip=g.ip)
                if tickets:
                    ticket, sid = tickets
                    returnUrl = "{}&ticket={}".format(sso_returnUrl, ticket)
                    return redirect(returnUrl)
                else:
                    flash(
                        dfr(dict(msg="Failed to create authorization ticket")))
            else:
                sessionId, returnUrl = checkSet_ssoTicketSid(
                    sso_isOk, sso_returnUrl, sso_appName, g.uid,
                    get_redirect_url("front.userset"))
                return set_redirectLoginstate(sessionId, returnUrl)
        return redirect(url_for("front.userset"))
    else:
        # 未登录时流程
        if request.method == 'POST':
            # POST请求不仅要设置登录态、还要设置全局会话
            res = dict(msg=None,
                       code=1,
                       nextUrl=url_for('.signIn', sso=sso)
                       if sso_isOk else url_for('.signIn'))
            if vaptcha.validate:
                auth = Authentication(g.mysql, g.redis)
                result = auth.signIn(account=request.form.get("account"),
                                     password=request.form.get("password"))
                if result["success"]:
                    # 记录登录日志
                    auth.brush_loginlog(result,
                                        login_ip=g.ip,
                                        user_agent=g.agent)
                    sessionId, returnUrl = checkSet_ssoTicketSid(
                        sso_isOk, sso_returnUrl, sso_appName, result["uid"],
                        get_redirect_url("front.userset"))
                    logger.debug("signIn post returnUrl: {}".format(returnUrl))
                    res.update(nextUrl=returnUrl, code=0)
                    return set_jsonifyLoginstate(sessionId, dfr(res))
                    #return set_redirectLoginstate(sessionId, returnUrl)
                else:
                    res.update(msg=result["msg"])
            else:
                res.update(msg="Man-machine verification failed")
            return jsonify(dfr(res))
            #return redirect(url_for('.signIn', sso=sso)) if sso_isOk else redirect(url_for('.signIn'))
        else:
            # GET请求仅用于渲染
            return render_template("auth/signIn.html",
                                   vaptcha=vaptcha.getChallenge)
Example #21
0
def OAuthGuide():
    """OAuth2登录未注册时引导路由(来源于OAuth goto_signUp),选择绑定已有账号或直接登录(首选)"""
    if request.method == 'POST':
        Action = request.args.get("Action")
        sso = request.args.get("sso") or None
        logger.debug("OAuthGuide, sso type: {}, content: {}".format(
            type(sso), sso))
        res = dict(msg=None, code=1)
        if Action == "bindLogin":
            if vaptcha.validate:
                auth = Authentication()
                result = auth.oauth2_bindLogin(
                    openid=request.form.get("openid"),
                    account=request.form.get("account"),
                    password=request.form.get("password"))
                if result["success"]:
                    # 记录登录日志
                    auth.brush_loginlog(result,
                                        login_ip=g.ip,
                                        user_agent=g.agent)
                    sso_isOk, sso_returnUrl, sso_appName = checkGet_ssoRequest(
                        sso)
                    sessionId, returnUrl = checkSet_ssoTicketSid(
                        sso_isOk, sso_returnUrl, sso_appName, result["uid"],
                        url_for("front.userset", _anchor="bind"))
                    logger.debug(
                        "OAuthGuide bindLogin post returnUrl: {}".format(
                            returnUrl))
                    res.update(nextUrl=returnUrl, code=0)
                    return set_jsonifyLoginstate(sessionId, dfr(res))
                    #return set_redirectLoginstate(sessionId, returnUrl)
                else:
                    res.update(msg=result["msg"])
            else:
                res.update(msg="Man-machine verification failed")
            return jsonify(dfr(res))
            #return redirect(url_for('.OAuthBindAccount', openid=openid, sso=sso))
        elif Action == "directLogin":
            auth = Authentication()
            # 直接注册新账号并设置登录态
            result = auth.oauth2_signUp(request.form.get("openid"), g.ip)
            if result["success"]:
                # 记录登录日志
                auth.brush_loginlog(
                    result,
                    login_ip=g.ip,
                    user_agent=request.headers.get("User-Agent"))
                sso_isOk, sso_returnUrl, sso_appName = checkGet_ssoRequest(sso)
                sessionId, returnUrl = checkSet_ssoTicketSid(
                    sso_isOk, sso_returnUrl, sso_appName, result["uid"],
                    url_for("front.userset", _anchor="bind"))
                logger.debug(
                    "OAuthGuide directLogin post returnUrl: {}".format(
                        returnUrl))
                res.update(nextUrl=returnUrl, code=0)
                return set_jsonifyLoginstate(sessionId, dfr(res))
                #return set_redirectLoginstate(sessionId, returnUrl)
            else:
                res.update(msg=result["msg"])
            return jsonify(dfr(res))
            #return redirect(url_for("front.OAuthGuide", openid=openid, sso=sso))
    else:
        if request.args.get("openid"):
            return render_template("auth/OAuthGuide.html",
                                   vaptcha=vaptcha.getChallenge)
        else:
            return redirect(g.redirect_uri)