钉钉第三方登录

钉钉第三方登录官方地址https://open.dingtalk.com/document/orgapp/tutorial-obtaining-user-personal-information

1.准备好前期工作

2.编写授权地址

https://login.dingtalk.com/oauth2/auth?
redirect_uri=http://127.0.0.1:8000/ding_back/  #重定向的地址
&response_type=code
&client_id=dingxxxxxxx   #应用的AppKey 
&scope=openid   #此处的openId保持不变
&prompt=consent

 3.接收前端参数,换取token

POST /v1.0/oauth2/userAccessToken HTTP/1.1
Host:api.dingtalk.com
Content-Type:application/json

{
  "clientId" : "String",
  "clientSecret" : "String",
  "code" : "String",
  "refreshToken" : "String",
  "grantType" : "String"
}
code = self.get_argument("authCode")
# 根据code换取token
async with httpx.AsyncClient() as client:
    ding_info = await client.post(url="https://api.dingtalk.com/v1.0/oauth2/userAccessToken",
                                  json={
                                      "clientId": SITE_TYPE["Dingding"]["client_id"],
                                      "clientSecret": SITE_TYPE["Dingding"]["client_secret"],
                                      "code": code,
                                      "grantType": "authorization_code"
                                  })
ding_info_json = json.loads(ding_info.text)
if "expireIn" not in ding_info_json:
    return self.finish({
        "code": 400,
        "msg": "token获取失败,原因%s" % ding_info.text
    })
ding_access_token = ding_info_json["accessToken"]

4.根据token换取用户信息

GET /v1.0/contact/users/{unionId} HTTP/1.1
Host:api.dingtalk.com
x-acs-dingtalk-access-token:String
Content-Type:application/json
async def get_info(self, ding_access_token):
    # 根据token换取用户信息
    async with httpx.AsyncClient() as client:
    ding = await client.get(url="https://api.dingtalk.com/v1.0/contact/users/me",
                            headers={
                                "x-acs-dingtalk-access-token": ding_access_token
                            })

    ding_json = json.loads(ding.text)

    username = ding_json["nick"]
    unionId = ding_json["unionId"]

    return unionId, username

async def get(self):

    ding_id, ding_name = await self.get_info(ding_access_token)

    username = (str(ding_id) + "_" + str(ding_name))

 5.查看用户是否第一次登录

try:
    # 曾经使用过dingding账号
    await db.get(UserModel.select().where((UserModel.username == username)
                                          & (UserModel.site_type == SITE_TYPE["Dingding"]["num"])))
except Exception as e:
    print(e.args)
    res = await db.create(UserModel, username=username,
                          site_type=SITE_TYPE["Dingding"]["num"])

6.重新生成有生命周期的token

finally:
    mj = MyJwt()
    # 生成带有生命周期的token
    token = mj.encode_date({
        "username": username,
        "site_type": SITE_TYPE["Dingding"]["num"]
    })
    # 生成refresh_token  redis里面存
    refresh_token = await mj.set_refresh_token(username)

url = "http://127.0.0.1:8080/center" + f"?ding_refresh_token={refresh_token}&ding_token={token}&username={username}"

return self.redirect(url)

完整代码

import httpx

# dingding登录
class Dingding(BaseHandler):
    async def get_info(self, ding_access_token):
        # 根据token换取用户信息
        async with httpx.AsyncClient() as client:
            ding = await client.get(url="https://api.dingtalk.com/v1.0/contact/users/me",
                                    headers={
                                        "x-acs-dingtalk-access-token": ding_access_token
                                    })

        ding_json = json.loads(ding.text)

        username = ding_json["nick"]
        unionId = ding_json["unionId"]

        return unionId, username

    async def get(self):
        code = self.get_argument("authCode")

        # 根据code换取token
        async with httpx.AsyncClient() as client:

            ding_info = await client.post(url="https://api.dingtalk.com/v1.0/oauth2/userAccessToken",
                                          json={
                                              "clientId": SITE_TYPE["Dingding"]["client_id"],
                                              "clientSecret": SITE_TYPE["Dingding"]["client_secret"],
                                              "code": code,
                                              "grantType": "authorization_code"
                                          })

        ding_info_json = json.loads(ding_info.text)

        if "expireIn" not in ding_info_json:
            return self.finish({
                "code": 400,
                "msg": "token获取失败,原因%s" % ding_info.text
            })

        ding_access_token = ding_info_json["accessToken"]

        ding_id, ding_name = await self.get_info(ding_access_token)

        username = (str(ding_id) + "_" + str(ding_name))

        try:
            # 曾经使用过dingding账号
            await db.get(UserModel.select().where((UserModel.username == username)
                                                  & (UserModel.site_type == SITE_TYPE["Dingding"]["num"])))

        except Exception as e:
            print(e.args)
            res = await db.create(UserModel, username=username,
                                  site_type=SITE_TYPE["Dingding"]["num"])

        finally:
            mj = MyJwt()
            # 生成带有生命周期的token
            token = mj.encode_date({
                "username": username,
                "site_type": SITE_TYPE["Dingding"]["num"]
            })
            # 生成refresh_token  redis里面存
            refresh_token = await mj.set_refresh_token(username)

        url = "http://127.0.0.1:8080/center" + f"?ding_refresh_token={refresh_token}&ding_token={token}&username={username}"

        return self.redirect(url)


# 路由
urlpatterns = [
    (r"/ding_back/", Dingding),  # dingding
]
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值