Using java to realize "nail micro-application, no login to a H5 system home page" function

I. Preface

Haha, this is my first blog.

Let's start with the specific scenario of this small function:

User login pin app, click on micro-application, get the current user information, and H5 system database user information comparison, if there is the user, then click directly into the H5 system home page, otherwise it shows "you have no rights".

Plus: Another small requirement is to send a message to the user if the logout is successful.

I'm referring to the pin development document to achieve this small function, document address: https://ding-doc.dingtalk.com/doc#/serverapi2/clotub

II. Preparations

You need to create a microapplication: https://open-dev.dingtalk.com

 

1. Creating H5 micro-applications in enterprise internal development, not in third-party enterprise applications

Enterprise internal development: Enterprise internal development refers to the "development of enterprise internal applications" for the use of personnel within the enterprise. Enterprises can choose to be developed by developers within the enterprise or by authorized customized service providers.

Third-party enterprise applications: third-party enterprise application development refers to the development of applications based on the open ability of nails by developers as a third party outside the enterprise, and provided to other organizations on nails for use. (Haha, the difference is in the direct copy file)

2.H5 project, created a front-end page ddNoLogin.html (Haha, this name is a little Chinese-English, because I did not find the appropriate English words):

This page is used to get the login-free authorization code, and then pass the code to the background interface.

3. Fill in the company server's public IP

You can click on the command to view the ip: curl ifconfig.me

4. When a microapplication is created, three parameters will be generated.

agentId,appKey,appSecret

Plus a corpId (shown on the home page of the nail developer platform), these four parameters are fixed, and subsequent development is required.

5. Interface permissions

Advanced Privileges - Interfaces in the Enterprise Address Book need to be opened

6. Final release and Application

3. Functional Development

Haha, it's time to start typing code.

1. Get the code of the login-free authorization code

The method invoked here is nailed in JS-API. The method invoked by this function does not need authentication. If authentication is needed, dd.config is needed first.

See the JSAPI overview about whether functional methods require authentication

ddNoLogin.html:

<!DOCTYPE html>
<html>
<head>
    <title>Microapplication landing</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1 user-scalable=0" />
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script type="text/javascript" src="http://g.alicdn.com/dingding/open-develop/1.9.0/dingtalk.js"></script>
</head>
<body>
<div id="ddNoLogin"></div>
<script type="text/javascript">
        dd.ready(function() {
		//1. Get the code of the login-free authorization code
		dd.runtime.permission.requestAuthCode({
			corpId : corpId ,  //Enterprise id
			onSuccess : function(result) {
				var code = result.code;
				getUserInfo(code);   //User identity can be obtained through this code
			},
			onFail : function(err) {
				alert('Error, ' + err);
			}
		});
	});
        function getUserInfo(code) {
		$.ajax({
			type : "GET",
			url : "/xxx/noLogin?code=" + code,
			async : false,
			dataType : 'json',
			contentType : "application/json;charset=utf-8",
			success : (function(res) {
				if(res.code == "0000"){					   				 
			           window.location.href = '/#/xxxxx';
                                }else{
                                   $('#ddNoLogin').html(res.msg);
                                }
			}),
		});
	}
</script>
</body>
</html>

The implementation of acquiring code needs to be written with front-end JS

2. Get access_token

Nails provide an open api backend interface, where token is obtained through appkey and appsecret, and the request path is https://oapi.dingtalk.com/gettoken?Appkey=key&appsecret=secret.

The token is valid for two hours. It is repeated within the validity period, returns the same result and renews automatically.

So my implementation here is to refresh token regularly, get token of nails every 1 hour and 50 minutes, and cache it in redis (I put the relevant configuration of nails into application.yml).

DdTokenTask.java:

/**
 * token for timing nail acquisition
 */
@Component
@EnableScheduling
public class DdTokenTask {

    @Autowired
    private JedisClient jedisClient;

    public static final long cacheTime = 1000 * 60 * 55 * 2;//1 hour 50 minutes
    @Value("${dtalk.tokenUrl}")
    private String tokenUrl;
    @Value("${dtalk.app.key}")
    private String appKey;
    @Value("${dtalk.app.secret}")
    private String appSecret;
    @Value("${dtalk.redisTokenKey}")
    private String tokenKey;
    @Value("${dtalk.taskRun}")
    private String taskRun;


    /**
     * Get access_token of nails every 1 hour and 50 minutes
     */
    @Scheduled(fixedRate = cacheTime)
    @Async
    public void getDdTokenTask(){
        if("true".equals(taskRun)){
            //Refresh
            System.out.println("--->>>>>-------------Get nails token The scheduled task begins:"+ DateUtil.formatDateToString(new Date(), "HH:mm:ss"));

            String accessTokenUrl = tokenUrl + "?appkey=" + appKey + "&appsecret=" + appSecret;
            //Access to access_token is valid for 2 hours
            String accessToken = JsonUtil.getJsonNode(HttpUtil.doGet(accessTokenUrl)).get("access_token").asText();
            //Put it in redis
            jedisClient.set(tokenKey, accessToken);

            System.out.println("--->>>>>-------------Get nails token The scheduled task is over. token: "+accessToken);
        }
    }

    /*private String getAccessToken(){
        //SDK needs to be introduced, the company does not have private service
        DefaultDingTalkClient client = new 
        DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
        OapiGettokenRequest request = new OapiGettokenRequest();
        request.setAppkey("appkey");
        request.setAppsecret("appsecret");
        request.setHttpMethod("GET");
        OapiGettokenResponse response = client.execute(request);
        return "";
    }*/

}

(Haha, in fact, the document provides a nail SDK java writing, but the company does not have the SDK private service, so I directly request with htttp)

3. Get user userid

Access_token=access_token&code=code:https://oapi.dingtalk.com/user/getuserinfo?Access_token=access_token&code=

4. Getting User Details

Request path: https://oapi.dingtalk.com/user/get?Access_token=ACCESS_TOKEN&userid=shaocui

Returns all information about the user's name, cell phone number, etc.

DdLoginController.java:

@RestController
@RequestMapping("/ddUser")
@Api(value = "/ddUser", description = "Nail H5 Microapplication login", tags = {"DdLoginController"})
public class DdLoginController {

    @Autowired
    private JedisClient jedisClient;

    @Value("${dtalk.userUrl}")
    private String userUrl;
    @Value("${dtalk.userDetailUrl}")
    private String userDetailUrl;
    @Value("${dtalk.redisTokenKey}")
    private String tokenKey;
    @Value("${dtalk.agentId}")
    private Integer agentId;


    @GetMapping("/noLogin")
    @ApiOperation( "Nail free access")
    @ApiImplicitParam(paramType = "query", name = "code", value = "Log-off Authorization Code", dataType = "String")
    public WebResponse noLogin(@RequestParam("code") String code, HttpServletResponse response){
        //2. Get access_token
        String accessToken = jedisClient.get(tokenKey);

        //3. Get user userid
        String userIdUrl =userUrl + "?access_token=" + accessToken + "&code=" + code;
        //Access to get userid
        JsonNode user = JsonUtil.getJsonNode(HttpUtil.doGet(userIdUrl));
        if(user.get("errcode").asInt() != 0){
            //In some companies, the public network ip is not fixed, which results in incorrect settings in micro-applications, and errors will be reported here.
            return WebResponse.resFail(user.get("errmsg").asText());
        }
        String userId = user.get("userid").asText();

        //4. Get User Details Mobile Number
        String userInfoUrl = userDetailUrl + "?access_token=" + accessToken + "&userid=" + userId;
        //Access to Get mobile
        JsonNode userInfo = JsonUtil.getJsonNode(HttpUtil.doGet(userInfoUrl));
        String mobile = userInfo.get("mobile").asText();

        System.out.println("Nail user's mobile phone number:"+mobile);

        //Get the user through the mobile phone number
        SysUser sysUser = . . . . . ;
        if(sysUser == null){
            //This user does not exist
            return WebResponse.resFail("You do not have permission to access", null);
        }

        . . . . . . 

        //Nail Send Log-Free Success Message to User
        sendMessage(accessToken, userId, userInfo.get("name").asText());

        return WebResponse.resSuccess("Free access to success", loginUserInfo);
    }

    //Nails send messages to users
    private void sendMessage(String token, String userId, String userName){
        String messageUrl = "https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2?access_token="+token;
        Map<String, Object> map = new HashMap<>();
        map.put("agent_id", agentId.longValue());
        map.put("userid_list", userId);
        map.put("to_all_user", false);
        String content = "user"+userName+"stay"+ DateUtil.formatDateToString(new Date(), "yyyy-MM-dd HH:mm:ss")+"Successful login xxH5 End, and enter xxx page";
        String msg = "{\"msgtype\":\"text\",\"text\":{\"content\":"+"\""+content+"\""+"}}";
        JSONObject jsonObj = JSONObject.parseObject(msg);
        map.put("msg",jsonObj);

        HttpUtil.doPost(messageUrl, map, "UTF-8", 20000, null);
    }
}

(Haha, that one... The code is the specific operation after the system authentication is successful, so it is omitted here.

At this point, the nail is exempted and the message is sent to the user after the exemption is successful.

5. Work Notification News

POST request, request path: https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2?access_token=ACCESS_TOKEN

Request body {agent_id, userid_list, dept_id_list, to_all_user, msg}

Be careful:

Send the same content to the same user only once a day, and send different content 500 times a day.

So here I added the current time to the message I sent.

(Ha-ha, I wrote some details in the comments of the code, and finally found that this little function seems like a little bit of code.)

Keywords: Java Mobile SDK JQuery

Added by deregular on Mon, 30 Sep 2019 15:00:03 +0300