基于华为welink H5轻应用的免登录实现
提示:IDEA java springboot maven html(H5的使用仅在手机端有效)
一、后台
1.实体类
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import javax.persistence.Entity;
@Entity
@Getter
@Setter
@ToString
public class UserResp {
private String code;
private String message;
private String userId;
private String tenantId;
}
2.controller层
import com.zykj.domain.h5Office.UserResp;
import com.zykj.welink.welinkUtil.H5Util;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@CrossOrigin
@RestController
@RequestMapping("/h5welink")
public class UserLinkController {
@Resource
private H5Util h5Util;
@RequestMapping(value = "/freelogin/{code}", method = RequestMethod.GET)
public UserResp getLinkUser(@PathVariable(value="code") String code) {
//获取免登code
// 免登code可以通过url参数从前端传过来
// 测试阶段可以通过WeLink扫码复制免登授权码使用https://open-doc.welink.huaweicloud.com/docs/devapi/wecode/jsapi/getAuthCode.html?type=internal
//String code = req.getParameter("code");
UserResp userResp = h5Util.getUserLink(code);
return userResp;
}
}
3.自定义工具类
@Component
public class H5Util {
@Autowired
public AccessTokenSingleton accessTokenSingleton;
@Autowired
public AccessTokenUtil accessTokenUtil;
private String userUrl = "https://open.welink.huaweicloud.com/api/auth/v2/userid";
private String jsAPI = "https://open.welink.huaweicloud.com/api/auth/v1/jstickets";
//得到当前登录用户信息
public UserResp getUserLink(String code){
//Step2:获取access token
//根据client_id,client_secret和已经获取的免登code等参数获取access_token信息
TicketResp ticketResp ;
//获取access token相关参数列表
AccessTokenUtil accessTokenUtil = new AccessTokenUtil();
String accessToken = accessTokenUtil.getToken(code);
//System.out.println("accessToken:"+accessToken);
//Step3:获取免登用户的userId信息
//通过access token获取免登用户的userId信息
Map<String, String> userHeaderParams = new HashMap<>();
UserResp userResp = null;
userHeaderParams.put("x-wlk-Authorization", accessToken);
Map<String, String> urlParams = new HashMap<>();
String codeValue =code;
urlParams.put("code", codeValue);
try{
//携带access token发送get请求并获取免登用户的userId信息
String userResult = OkHttpUtil.get(userUrl, userHeaderParams, urlParams);
//System.out.println("userinfo response: " + userResult);
userResp = JSON.parseObject(userResult, UserResp.class);
}
catch (Exception e)
{
e.printStackTrace();
ExceptionUtil.getExceptionInfo(e);
}
//System.out.println(userResp.toString());
return userResp;
}
}
4.得到access-token的工具类
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zykj.domain.h5Office.TicketResp;
import okhttp3.MediaType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class AccessTokenUtil {
public static final MediaType mediaType = MediaType.parse("application/json");
private String ticketUrl = "https://open.welink.huaweicloud.com/api/auth/v2/tickets";
private String userUrl = "https://open.welink.huaweicloud.com/api/auth/v2/userid";
private String clientId ="";//自己的clientId
private String clientSecret = "";//自己的clientSecret
//线程不安全的
private long timeStamp = 0;
private int timeSlot = 7190;
String accessToken="";
public String getToken(String code){
System.out.println("code:"+code);
long endtime = System.currentTimeMillis();
if ((endtime - timeStamp)/1000 > timeSlot ){
accessToken = getAccessToken(code);
timeStamp = System.currentTimeMillis();
System.out.println("重新获取了access:"+accessToken);
return accessToken;
}else{
return accessToken;
}
}
public String getAccessToken(String code){
//Step2:获取access token
//根据client_id,client_secret和已经获取的免登code等参数获取access_token信息
TicketResp ticketResp ;
//获取access token相关参数列表
String typeParamValue = "u";
String clientIdParamValue =clientId ;
String clientSecretParamValue = clientSecret;
if (clientId == null || clientId.equals("")) {
System.out.println("请根据README.md文档配置client_id和client_secret");
System.exit(1);
}
String stateValue = "1";
Map<String, String> ticketBodyParams = new HashMap<>();
ticketBodyParams.put("client_id", clientIdParamValue);
ticketBodyParams.put("client_secret", clientSecretParamValue);
//转换相关参数列表为Json格式
String ticketBody = JSONObject.toJSONString(ticketBodyParams);
try {
//发送post请求并获取access token相关信息
String ticketResult = OkHttpUtil.post(ticketUrl, ticketBody, mediaType);
ticketResp = JSON.parseObject(ticketResult, TicketResp.class);
// 请务必根据接口过期时间缓存AccessToken,避免重复获取
accessToken = ticketResp!=null?ticketResp.getAccess_token():null;
} catch (Exception e) {
e.printStackTrace();
return ExceptionUtil.getExceptionInfo(e);
}
return accessToken;
}
}
5.OKUtil工具类
import okhttp3.*;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
public class OkHttpUtil {
private static OkHttpClient okHttpClient = new OkHttpClient();
public static String get(String url, Map<String, String> headers, Map<String, String> urlParams) throws IOException {
String result = "";
Request.Builder builder = new Request.Builder();
if (StringUtils.isEmpty(url)) {
return result;
}
if (headers != null) {
builder.headers(setHeaders(headers));
}
if (urlParams != null) {
builder.url(setUrlParams(url, urlParams));
} else {
builder.url(url);
}
Request request = builder.build();
Response response = okHttpClient.newCall(request).execute();
result = response.body().string();
return result;
}
public static String post(String url, String json,MediaType mediaType) throws IOException {
RequestBody body = RequestBody.create(mediaType, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = okHttpClient.newCall(request).execute();
return response.body().string();
}
private static Headers setHeaders(Map<String, String> headersParams) {
Headers headers = null;
Headers.Builder headersbuilder = new Headers.Builder();
if (headersParams != null) {
Iterator<String> iterator = headersParams.keySet().iterator();
String key = "";
while (iterator.hasNext()) {
key = iterator.next().toString();
headersbuilder.add(key, headersParams.get(key));
}
}
headers = headersbuilder.build();
return headers;
}
private static String setUrlParams(String url, Map<String, String> mapParams) {
String strParams = "";
if (mapParams != null) {
Iterator<String> iterator = mapParams.keySet().iterator();
String key = "";
while (iterator.hasNext()) {
key = iterator.next().toString();
strParams += "&" + key + "=" + mapParams.get(key);
}
if (url.endsWith("?")) {
url += strParams;
} else {
url += "?" + strParams;
}
}
return url;
}
}
6.exception工具类
import java.io.PrintWriter;
import java.io.StringWriter;
public class ExceptionUtil {
public static String getExceptionInfo(Exception exception) {
try {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
exception.printStackTrace(pw);
return "\r\n" + sw.toString() + "\r\n";
} catch (Exception e) {
e.printStackTrace();
return "bad getErrorInfoFromException";
}
}
}
二、pom依赖
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.6.0</version>
</dependency>
三、前台
1.引入h5 js
<script src="https://open-doc.welink.huaweicloud.com/docs/jsapi/2.0.3/hwh5-cloudonline.js"></script>
2.使用h5 得到code传到后台(两分钟更新一次)
HWH5.getAuthCode().then(function (data) {
console.log(data.code);
var code = data.code;
在这里将code传到后台
还可以做一些其他操作
}).catch(function (error) {
alert(error);
console.log('获取异常', error);
});
到这里h5免登录的操作就已经做完了,需要注意的是 免登录只有在手机端测试才可以
最后
附上一些链接:
注意:(因为code两分钟过期,且只能使用一次,所以在测试阶段可以用welink扫码获取临时的code)
[H5轻应用免登码]:
https://open-doc.welink.huaweicloud.com/docs/devapi/wecode/jsapi/getAuthCode.html?type=internal
[welink官网]:
https://open.welink.huaweicloud.com/wecode-site/index.html#/home