• springboot实现第三方钉钉扫码登录


     本篇博客主要作为本人的日记,如果各位博友对以下内容有所疑问欢迎留言探讨。

    一、准备工作

    1、钉钉开放平台注册登录:

            登录地址:https://open.dingtalk.com/

    2、注册登录成功后选择你加入的组织

     3、创建应用 

    4、相关权限开通(权限开通都是免费) 

     5、设置扫描成功后的回调域名

      如果开发者没有域名可以随便写一个域名,在本地host中配置对应的域名即可

     

     6、本地host文件配置域名

      host文件路径为:C:\Windows\System32\drivers\etc\host,打开host文件添加以上输入的回调域名,本人写的回调地址为“www.chenyuanbo.com”,配置如下所示:

    7、开发环境下配置好内网穿透

      (1)登录natApp官网注册;https://natapp.cn/,在右上角点击“客户端下载”,下载对应的natApp客户端,登录成功后的界面如下,authToken用于启动natApp

     (2)启动内网穿透

      打开下载好的natApp,运行natapp.exe,输入命令:natapp -authtoken="NatApp的隧道authtoken",出现以下界面说明内网穿透启动已成功

    二、功能实现思路:

    1、获取钉钉二维码界面(即下方:dingdingLogin方法)

    2、扫二维码成功后进入回调方法,获取code。

    3、请求获取accessToken

    4、根据code和accessToken获取用户信息(含用户openId)

    5、根据用户openId去自己系统的用户表中查询是否存在对应的用户,如果存在则登录成功,跳转至系统首页

    三、功能开发

      1、maven坐标:

         <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>dingtalk</artifactId>
                <version>1.2.43</version>
            </dependency>
            <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>alibaba-dingtalk-service-sdk</artifactId>
                <version>2.0.0</version>
            </dependency>

      2、具体代码实现

    package com.cyb.sso.server.controller;
    
    import com.dingtalk.api.DefaultDingTalkClient;
    import com.dingtalk.api.DingTalkClient;
    import com.dingtalk.api.request.OapiGettokenRequest;
    import com.dingtalk.api.request.OapiSnsGetuserinfoBycodeRequest;
    import com.dingtalk.api.response.OapiGettokenResponse;
    import com.dingtalk.api.response.OapiSnsGetuserinfoBycodeResponse;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    
    /**
     *@ClassName UnionLoginController
     *@Description 联合登录控制层
     *@Author cyb
     *@Date 2022/1/25 23:06
     */
    @Controller
    @RequestMapping("/unionLogin")
    @Slf4j
    public class UnionLoginController {
    
        /***
         * 钉钉APPKey或SuiteKey
         */
        private static final  String DING_TALK_APP_ID="dingrd9jvv0i2z0eu62q";
    
        /***
         * 钉钉SuiteSecret或appSecret
         */
        private static final String DING_TALK_SECRET ="HkOsehRYCwhJBg-nChBGdxAg2eoLA9A3T1ykbR1kR4HU5XzrO_D79s8Y6BJ-Pjzy";
    
        /***
         * 钉钉扫码后回调地址
         * http://www.chenyuanbo.com:8080/xxl-sso-server/unionLogin/dingdingCallback
         */
        private static final String DING_TALK_CALL_BACK_URL = "http%3A%2F%2Fwww.chenyuanbo.com%3A8080%2Fxxl-sso-server%2FunionLogin%2FdingdingCallback";
    
        /***
         * 获取accessToken请求URL
         */
        private static final String getTokenUrl ="https://oapi.dingtalk.com/gettoken";
    
        /***
         * 获取用户详情URL
         */
        private static final String getUserInfoUrl= ":https://oapi.dingtalk.com/sns/getuserinfo_bycode";
    
        /***
         * 获取钉钉联合登录二维码
         * @return 钉钉二维码
         */
        @ResponseBody
        @RequestMapping("/dingdingLogin")
        public Object dingdingLogin() {
            String time = String.valueOf(System.currentTimeMillis());//产生一个当前的毫秒
            StringBuilder stringBuilder = new StringBuilder();
            String result="";
            stringBuilder
                    .append("https://oapi.dingtalk.com/connect/qrconnect?appid=")
                    .append(DING_TALK_APP_ID)//APP_ID
                    .append("&response_type=")
                    .append("code")//code
                    .append("&scope=")
                    .append("snsapi_login")//snsapi_login
                    .append("&state=")
                    .append(time)
                    .append("&redirect_uri=")
                    .append(DING_TALK_CALL_BACK_URL);//回调地址
            try {
                result = stringBuilder.toString();
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
            return result;
        }
    
        /***
         * 扫码后的回调方法
         * @param code 钉钉扫码返回的code
         * @return
         */
        @RequestMapping(value="/dingdingCallback", produces="text/html; charset=utf-8")
        public Object getUserInfo(String code) {
    
           log.info("进入回调");
           //1、获取accesstoken
            String accessToken = getAccessToken();
            if(StringUtils.isEmpty(accessToken)){
                return "未获取到accessToken,跳转到登录页";
            }
            //2、根据accessToken和code获取用户OpenId
            String openId = getPersistentCode(accessToken, code);
            if(StringUtils.isEmpty(openId)){
                return "未获取到用户OpenId,跳转到登录页使用账户密码登录";
            }
            //3、根据openId查询数据库用户表,如果查询到用户则登录成功,未查询到则返回到登录首页使用账号密码登录并进行绑定钉钉openId
    
            return null;
        }
    
    
         /**
          * @method  获取accesstoken
          * @description 获取accesstoken
          * @date: 2022/1/26 22:00
          * @author: cyb
          * @return 钉钉accessToken
          */
        public String getAccessToken() {
            try {
            DingTalkClient clientDingTalkClient = new DefaultDingTalkClient(getTokenUrl);
            OapiGettokenRequest request = new OapiGettokenRequest();
            // 填写步骤一创建应用的Appkey
            request.setAppkey(DING_TALK_APP_ID);
            // 填写步骤一创建应用的Appsecret
            request.setAppsecret(DING_TALK_SECRET);
            request.setHttpMethod("GET");
            OapiGettokenResponse response =clientDingTalkClient.execute(request);
            if(response.getErrcode() == 0){
                return response.getAccessToken();
            }
            log.info("获取accessToken失败:{}",response.getMsg());
            }catch (Exception e){
                log.error("获取accessToken失败:",e);
            }
            return null;
        }
    
         /**
          * @method  getPersistentCode
          * @description 获取用户openId
          * @date: 2022/1/26 22:08
          * @author: cyb
          * @param accessToken 用户的accessToken
          * @param code 扫码返回的code
          * @return openId
          */
        public String getPersistentCode(String accessToken,String code)  {
            try {
                DefaultDingTalkClient  client = new DefaultDingTalkClient(getUserInfoUrl);
                OapiSnsGetuserinfoBycodeRequest req = new OapiSnsGetuserinfoBycodeRequest();
                req.setTmpAuthCode(code);
                OapiSnsGetuserinfoBycodeResponse response = client.execute(req,DING_TALK_APP_ID,DING_TALK_SECRET);
                if(0 != response.getErrcode()){
                    return null;
                }
                OapiSnsGetuserinfoBycodeResponse.UserInfo userInfo = response.getUserInfo();
                if(null != userInfo){
                    return  userInfo.getOpenid();
                }
            }catch (Exception e){
                log.error("获取用户信息失败:",e);
            }
            return null;
        }
    
    
    }

    以上则为钉钉扫码登录的主要流程,如有其他功能需求,可以查阅官网的文档说明,以扫码登录为例,访问网站:https://open.dingtalk.com/document/orgapp-server/obtain-the-user-information-based-on-the-sns-temporary-authorization。转载请说明出处

  • 相关阅读:
    window 7 安装Jmeter并配置https录制脚本
    windows 7安装Fiddler抓HTTPS请求的解决办法
    APP界面设计与页面布局的23条基本原则
    Charles 连接手机抓包出现Unknown,一直无法抓包的问题解决
    Charles 如何破解与连接手机进行抓包
    WeTest----如何查看Wetest生成测试报告?
    WeTest----如何使用WeTest进行App性能测试?
    兼容位图
    DeleteDC ReleaseDC DeleteObject之间的区别
    屏幕保存为位图
  • 原文地址:https://www.cnblogs.com/chenyuanbo/p/15848567.html
Copyright © 2020-2023  润新知