Exemple #1
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)
Exemple #2
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)
Exemple #3
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)
Exemple #4
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)