123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- package com.ruoyi.system.service.dingding;
- import com.aliyun.dingtalkoauth2_1_0.Client;
- import com.aliyun.dingtalkoauth2_1_0.models.GetUserTokenRequest;
- import com.aliyun.dingtalkoauth2_1_0.models.GetUserTokenResponse;
- import com.aliyun.teaopenapi.models.Config;
- import com.dingtalk.api.DefaultDingTalkClient;
- import com.dingtalk.api.request.OapiGetJsapiTicketRequest;
- import com.dingtalk.api.request.OapiGettokenRequest;
- import com.dingtalk.api.response.OapiGetJsapiTicketResponse;
- import com.dingtalk.api.response.OapiGettokenResponse;
- import com.ruoyi.common.constant.Constants;
- import com.ruoyi.common.core.domain.AjaxResult;
- import com.ruoyi.common.core.redis.RedisCache;
- import com.ruoyi.common.utils.dingding.config.DingAppConfig;
- import com.ruoyi.common.utils.dingding.config.DingUrlConstant;
- import com.taobao.api.ApiException;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.stereotype.Service;
- import javax.annotation.Resource;
- import java.util.concurrent.TimeUnit;
- /**
- * <p>DingLoginController 此类用于:获取access_token 和 jsTicket方法</p>
- * <p>@remark:钉钉企业内部微应用DEMO, 实现了身份验证(免登)功能</p>
- */
- @Slf4j
- @Service
- public class DingTokenService {
- @Resource
- private RedisCache redisCache;
- /**
- * 缓存时间:一小时50分钟
- */
- private static final Integer CACHE_TTL = 60 * 55 * 2;
- @Resource
- private DingAppConfig dingAppConfig;
- /**
- * 在此方法中,为了避免频繁获取access_token,
- * 在距离上一次获取access_token时间在两个小时之内的情况,
- * 将直接从持久化存储中读取access_token
- * <p>
- * 因为access_token和jsapi_ticket的过期时间都是7200秒
- * 所以在获取access_token的同时也去获取了jsapi_ticket
- * 注:jsapi_ticket是在前端页面JSAPI做权限验证配置的时候需要使用的
- * 具体信息请查看开发者文档--权限验证配置
- *
- * @return accessToken 或错误信息
- */
- public AjaxResult getAccessToken() {
- // 从持久化存储中读取
- String accessToken = redisCache.getCacheObject(Constants.DAILY_DING_ACCESS_TOKEN);
- log.info("从Redis缓存中获取到的accessToken = {}", accessToken);
- if (accessToken != null) {
- return AjaxResult.success(accessToken);
- }
- DefaultDingTalkClient client = new DefaultDingTalkClient(DingUrlConstant.URL_GET_TOKEN);
- OapiGettokenRequest request = new OapiGettokenRequest();
- OapiGettokenResponse response;
- request.setAppkey(dingAppConfig.getAppKey());
- request.setAppsecret(dingAppConfig.getAppSecret());
- request.setHttpMethod("GET");
- try {
- response = client.execute(request);
- } catch (ApiException e) {
- log.error("getAccessToken failed", e);
- return AjaxResult.error(e.getErrCode(), e.getErrMsg());
- }
- accessToken = response.getAccessToken();
- log.info("向Redis缓存中存取accessToken = {}", accessToken);
- redisCache.setCacheObject(Constants.DAILY_DING_ACCESS_TOKEN, accessToken, CACHE_TTL, TimeUnit.MINUTES);
- return AjaxResult.success(accessToken);
- }
- /**
- * 使用 Token 初始化账号Client
- * @return Client
- * @throws Exception
- */
- public static Client createClient() throws Exception {
- Config config = new Config();
- config.protocol = "https";
- config.regionId = "central";
- return new Client(config);
- }
- /**
- * 获取用户toKen
- * @return
- */
- public AjaxResult getUserAccessToken(String code){
- try {
- Client client = this.createClient();
- GetUserTokenRequest request = new GetUserTokenRequest()
- .setClientSecret(dingAppConfig.getAppSecret())
- .setClientId(dingAppConfig.getAppKey())
- .setCode(code).setGrantType(Constants.AUTHORIZATION_CODE);
- GetUserTokenResponse response;
- response = client.getUserToken(request);
- return AjaxResult.success(response.getBody().getAccessToken(),response.getBody());
- } catch (ApiException e) {
- log.error("getAccessToken failed", e);
- return AjaxResult.error(e.getErrCode(), e.getErrMsg());
- } catch (Exception e) {
- log.error("getAccessToken failed", e);
- return AjaxResult.error(e.hashCode(), e.getMessage());
- }
- }
- /**
- * 获取JSTicket, 用于js的签名计算
- * 正常的情况下,jsapi_ticket的有效期为7200秒,所以开发者需要在某个地方设计一个定时器,定期去更新jsapi_ticket
- *
- * @return jsTicket或错误信息
- */
- public AjaxResult getJsTicket() {
- // 从持久化存储中读取
- String ticket = redisCache.getCacheObject(Constants.DAILY_DING_JS_TICKET);
- if (ticket != null) {
- return AjaxResult.success(ticket);
- }
- String accessToken;
- AjaxResult tokenSr = getAccessToken();
- if (!tokenSr.isSuccess()) {
- return tokenSr;
- }
- accessToken = (String) tokenSr.get(tokenSr.MSG_TAG);
- DefaultDingTalkClient client = new DefaultDingTalkClient(DingUrlConstant.URL_GET_JSTICKET);
- OapiGetJsapiTicketRequest request = new OapiGetJsapiTicketRequest();
- OapiGetJsapiTicketResponse response;
- request.setHttpMethod("GET");
- try {
- response = client.execute(request, accessToken);
- } catch (ApiException e) {
- log.error("getAccessToken failed", e);
- return AjaxResult.error(e.getErrCode(), e.getErrMsg());
- }
- if (!response.isSuccess()) {
- return AjaxResult.error(response.getErrorCode(), response.getErrmsg());
- }
- ticket = response.getTicket();
- redisCache.setCacheObject(Constants.DAILY_DING_JS_TICKET, ticket, CACHE_TTL, TimeUnit.SECONDS);
- return AjaxResult.success(ticket);
- }
- }
|