Example #1
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 #2
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 #3
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 #4
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 #5
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 #6
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 #7
0
 def oauth2_go(self, name, signin, tokeninfo, userinfo, uid=None):
     """第三方账号登录入口
     参数:
         @param name str: 开放平台标识,参见`oauth2_name2type`函数
         @param signin bool: 是否已登录
         @param tokeninfo dict: access_token数据,格式:
             {
                 "access_token": "ACCESS_TOKEN",
                 "expires_in": "可选,到期时间戳,默认0不限制",
                 "refresh_token": "可选,刷新TOKEN"
             }
         @param userinfo dict: 用户数据,包含用户基本信息及用户在第三方网站唯一标识,主要用于注册流程,格式:
             {
                 "openid": "用户唯一标识",
                 "nick_name": "昵称",
                 "avatar": "头像地址",
                 "gender": "可选,性别",默认2,
                 "signature": "可选,签名,针对github"
             }
         @param uid str: 系统本地用户id,当`signin=True`时,此值必须为实际用户id
     流程:
         1. signin字段判断是否登录
         - 已登录,说明已有账号,只需绑定账号即可
             1. 判断uid参数,有意义则查询openid是否绑定uid,否则返回失败信息。
             2. 如果openid返回uid,说明已经绑定,然后判断绑定账号与uid参数是否一致,一致则尝试更新绑定数据,完成绑定;不一致表示已经绑定其他账号,拒绝操作并返回原页面。
             3. 如果openid返回None,说明没有绑定,则直接注册并绑定uid参数。
         - 未登录,可能无账号、可能有账号,需要直接注册或绑定已有
             1. 查询openid是否绑定uid。
             2. 如果openid返回uid,说明已经绑定,转入登录流程,需要设置cookie登录状态。
             3. 如果openid返回None,说明没有绑定,此时需要设置是否页面绑定本地账号或直接注册。
     """
     res = dict(msg=None, success=False, pageAction=None)
     if isinstance(name, (str, unicode)) and \
             signin in (True, False) and \
             isinstance(tokeninfo, dict) and \
             isinstance(userinfo, dict) and \
             "access_token" in tokeninfo and \
             "openid" in userinfo and \
             "nick_name" in userinfo and \
             "avatar" in userinfo:
         # openid是第三方平台用户唯一标识,微博是uid,QQ是openid,Github是id,统一更新为openid
         access_token = tokeninfo["access_token"]
         expires_in = tokeninfo.get("expires_in") or 0
         # 重新定义openid规则->加上开放平台前缀
         openid = "{}.{}".format(oauth2_name2type(name), userinfo["openid"])
         # 覆盖原openid
         userinfo.update(openid=openid)
         if signin is True:
             # 已登录->绑定流程
             logger.debug("signin true, uid: {}".format(uid))
             if uid:
                 guid = self.__oauth2_getUid(openid)
                 logger.debug("signin true, openid: {}, guid: {}, is equal: {}".format(openid, guid, uid == guid))
                 if guid:
                     if uid == guid:
                         # 更新绑定的数据
                         res.update(success=True)
                     else:
                         res.update(msg="Has been bound to other accounts")
                 else:
                     # 此openid没有绑定任何本地账号,更新用户资料
                     upts = self.__signUp_transacion(guid=uid, identifier=openid, identity_type=oauth2_name2type(name), certificate=access_token, verified=1, expire_time=expires_in, use_profile_sql=False)
                     res.update(upts)
             else:
                 res.update(msg="Third-party login binding failed")
         else:
             # 未登录->注册绑定流程
             guid = self.__oauth2_getUid(openid)
             if guid:
                 # 已经绑定过账号,需要设置登录态
                 res.update(pageAction="goto_signIn", goto_signIn_data=dict(guid=guid))
             else:
                 # 尚未绑定,需要绑定注册
                 userinfo.update(identity_type=oauth2_name2type(name), access_token=access_token, expires_in=expires_in)
                 if self.__oauth2_setUserinfo(userinfo):
                     res.update(pageAction="goto_signUp", goto_signUp_data=dict(openid=cbc.encrypt(openid)))
                 else:
                     res.update(msg="System is abnormal")
     else:
         res.update(msg="Check failed")
     logger.info(res)
     return res