钉钉登录操作流程

钉钉登录教程:地址(教程比较详细可以参考)

https://open.dingtalk.com/document/isvapp-server/tutorial-enabling-login-to-third-party-websites

步骤一:登录钉钉开发者后台,创建并配置应用。在此省略可以参考 教程操作;
步骤二:添加接口权限 (省略;参考文档)

步骤四:设置第三方网站的回调域名(回调域名为)  如下:

服务器出口IP
127.0.0.1
应用首页地址(随便设置就如下:)
https://www.dingtalk.com


步骤六:构造登录的第三方网站的访问地址

赋值官网给我们的地址进行修改如下:


https://login.dingtalk.com/oauth2/auth?
redirect_uri=https%3A%2F%2Fwww.aaaaa.com%2Fauth
&response_type=code
&client_id=dingxxxxxxx   //应用的AppKey 
&scope=openid   //此处的openId保持不变
&state=dddd
&prompt=consent

只修改 redirect_uri  和   &client_id  其他的不变(将这个地址居中到一行可以访问到钉钉登录的页面;可以进行测试)

https://login.dingtalk.com/oauth2/auth?
redirect_uri= http://127.0.0.1:8080/  #登录成功跳转的地址
&response_type=code
&client_id= ding9rhrejenvap5hia0   #自己配置文件中的  AppKey
&scope=openid   
&prompt=consent    
# &state=dddd  这个不要


步骤七:访问第三方网站地址
(点击官网步骤下的  “获取token” 蓝色字体  会有具体教程)

如他让我们向这个地址发一个post 请求传以下参数:
教程有参数具体解释

请求方法
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"
}

如:
https://api.dingtalk.com/v1.0/oauth2/userAccessToken
返回参数:

{
    "expireIn": 7200,
    "accessToken": "a0689fe599233315a1ba01fa50f13482",  // 返回的token
    "refreshToken": "11f1d7426ce43354bf0e129d7fa017a5"
}

下一步:
根据用户个人token,调用获取用户通讯录个人信息接口
(点击官网步骤下的  “获取用户通讯录个人信息 蓝色字体”  会有具体教程)

如下:
他让我们向这个地址发一个post 请求传以下参数(主要是:accessToken):
教程有参数具体解释

GET /v1.0/contact/users/{unionId} HTTP/1.1
Host:api.dingtalk.com
x-acs-dingtalk-access-token:String
Content-Type:application/json

按照步骤进行操作如下:

https://api.dingtalk.com/v1.0/contact/users/me

参数名:x-acs-dingtalk-access-token
值: 获取到的 accessToken

获取的参数如下:
就是我们的个人信息

{
    "nick": "张海军",
    "unionId": "norcFSzouL0yMxuFtTiPnVAiEiE",
    "avatarUrl": "https://static-legacy.dingtalk.com/media/lADPD4PvPdGlUqTNAbDNAbA_432_432.jpg",
    "openId": "iiP1Netz9FmO0IpuAiSwkhEgiEiE",
    "mobile": "17550333172",
    "stateCode": "86"
}


                                                                                 实战应用:


                                                                               前段:

// 绑定事件 ; 点击钉钉登录时触发
 // url  拼接的钉钉登录地址
          const url = 'https://login.dingtalk.com/oauth2/auth?redirect_uri=http://127.0.0.1:8080/about&response_type=code&client_id=ding9rhrejenvap5hia0&scope=openid&prompt=consent'
          window.location.href = url


// 登录成功;跳转首页 向后端发送code


get_dinidindg(){
        // 获取地址栏中的code
        const code =  this.$route.query.authCode  || ""
        // 如果没有获取到code,那就直接终止了,不向后端发起请求了;
        if (!code){
          return
        }
        // 根据code 获取换token
         Axios.get('http://127.0.0.1:5000/ding_login',{
         params:{
           code:code
         }
         })
        .then(res=>{
          console.log(res,'钉钉登录的响应')
          localStorage.setItem('token',res.data.token)
          this.$router.push('/about')
        })
        .catch(ree=>{
          console.log(ree,'钉钉登录的响应失败')
        })
      }

                                                                                                               后端:


# 钉钉登录 拿code换取token
class DingLoogin(Resource):
    def get(self):
        resp = reqparse.RequestParser()
        resp.add_argument('code')
        aegs = resp.parse_args()
        #根据code 换取token
        if not aegs['code']:
            return jsonify({
                'code':400,
                'msg':"code不存在"
            })
        # requests 可以帮助我们在code中发请求
        import requests
        # 发起请求或获取token
        #下面为发起请求的地址
        rs =requests.post('https://api.dingtalk.com/v1.0/oauth2/userAccessToken',json={
                # 携带参数
                # 这是AppKey
                "clientId": "ding9rhrejenvap5hia0",
                #AppSecret
                "clientSecret": "fngiXZ3tQy3hDLHgztylquliMLhkqXRUsE1L_1weLsvy10HmSLrLNzJE5dpif7UG",
                "code": aegs['code'],
                # 如果使用刷新token换用户token,传refresh_token。
                # 如果使用授权码换token,传authorization_code。
                "grantType": "authorization_code"
        })
        #将拿到的响应码进行转码;判断是否发送成功
        rea_date = json.loads(rs.text)
        if 'expireIn' not  in rea_date:
            return jsonify({
                'code':400,
                'msg':rea_date
            })
        token = rea_date['accessToken']
        #根据token拿用户信息
        res2 = requests.get('https://api.dingtalk.com/v1.0/contact/users/me',headers={
            'x-acs-dingtalk-access-token':token
        })
        user = json.loads(res2.text)
        #拿到用户名和手机号之后判断是否注册
        user_if = UserModel.query.filter(UserModel.mobile == user['mobile']).first()
        # 查看用户是否注册没注册进行注册
        if not user_if:
            u = UserModel(username = user['nick'],mobile=user['mobile'],password=generate_password_hash('tom123456'))
            db.session.add(u)
            db.session.commit()
        #注册成功进行登录,返回一个token做本地存储
        user_app = UserModel.query.filter(UserModel.mobile == user['mobile']).first()
        token = self.toekn_app(user_app)
        return jsonify({
            'code': 200,
            'msg': '登陆成功',
            'token': token,
        })

    @staticmethod
    def toekn_app(user):
        """
        :param user: 用户查询对象
        :return: jwt token
        """
        payload = {
            'uid': user.id,
            'exp': time.time() + 7200 * 12
        }
        key = current_app.config.get('SECRET_KEY')
        token = jwt.encode(payload, key, algorithm='HS256')
        return token


 

你可能感兴趣的:(flask,后端,钉钉,servlet,java)