zyx 2 жил өмнө
parent
commit
0bc74cd418

+ 9 - 1
src/main/java/com/sxtvs/open/api/odata/controller/OauthController.java

@@ -3,6 +3,8 @@ package com.sxtvs.open.api.odata.controller;
 import cn.hutool.core.util.IdUtil;
 import com.sxtvs.open.api.odata.dto.wx.WxApiCreatePreAuthCodeResponse;
 import com.sxtvs.open.api.odata.service.OauthService;
+import com.sxtvs.open.core.auth.HttpContextUtil;
+import com.sxtvs.open.core.auth.LoginRequired;
 import com.sxtvs.open.core.conf.OauthConfig;
 import com.sxtvs.open.core.sls.AliyunLogger;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -13,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.servlet.ModelAndView;
 
 import java.util.Map;
+import java.util.Optional;
 
 @Controller
 @RequestMapping("oauth")
@@ -26,9 +29,12 @@ public class OauthController {
     private AliyunLogger logger;
 
     @RequestMapping("douyin/code")
+    @LoginRequired
     public String douyinQrCode() {
         var state = IdUtil.nanoId();
+        var token = HttpContextUtil.mustToken();
         logger.info("key", "oauth/douyin/code", "state", state);
+        oauthService.saveStateMapping(token, state);
         return "redirect:https://open.douyin.com/platform/oauth/connect/?" +
                 "client_key=awfrca76s1petwh0&response_type=code&" +
                 "scope=video.data%2Cfans.list%2Cdata.external.item%2Cdata.external.user%2Cfans.data%2Cvideo.list%2Crenew_refresh_token%2Cuser_info&" +
@@ -37,7 +43,8 @@ public class OauthController {
 
     @RequestMapping("douyin/callback")
     public String douyinCallback(String code, String state) {
-        logger.info("key", "oauth/douyin/callback", "code", code, "state", state);
+        var token = oauthService.loadStateMapping(state);
+        logger.info("key", "oauth/douyin/callback", "code", code, "state", state, "token", token);
         return "redirect:https://www.baidu.com";
     }
 
@@ -107,6 +114,7 @@ public class OauthController {
         WxApiCreatePreAuthCodeResponse preAuthCodeResponse = oauthService.createPreAuthCodeResponse();
         ModelAndView view = new ModelAndView();
         view.setViewName("weixin-code");
+        // 这里使用预授权码跟用户token做一个映射
         view.addObject("pre_auth_code", preAuthCodeResponse.getPreAuthCode());
         return view;
     }

+ 12 - 0
src/main/java/com/sxtvs/open/api/odata/service/OauthService.java

@@ -12,6 +12,8 @@ import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Service;
 
 import java.nio.charset.StandardCharsets;
+import java.time.Duration;
+import java.util.Optional;
 
 @Service
 public class OauthService {
@@ -49,4 +51,14 @@ public class OauthService {
 
         return objectMapper.readValue(body, WxApiCreatePreAuthCodeResponse.class);
     }
+
+    public void saveStateMapping(String token, String state) {
+        redisTemplate.opsForValue().set("OAUTH_STATE:" + state, token, Duration.ofMinutes(3));
+    }
+
+    public Optional<String> loadStateMapping(String state) {
+        var token = redisTemplate.opsForValue().get("OAUTH_STATE:" + state);
+        return Optional.ofNullable(token);
+    }
+
 }

+ 7 - 0
src/main/java/com/sxtvs/open/core/auth/HttpContextUtil.java

@@ -34,6 +34,13 @@ public class HttpContextUtil {
                 .map(Object::toString);
     }
 
+    public static String mustToken() {
+        return Optional.ofNullable(RequestContextHolder.getRequestAttributes())
+                .map(x -> x.getAttribute("token", RequestAttributes.SCOPE_REQUEST))
+                .map(Object::toString)
+                .orElseThrow();
+    }
+
     public static void setToken(String token) {
         Optional.ofNullable(RequestContextHolder.getRequestAttributes())
                 .ifPresent(x -> x.setAttribute("token", token, RequestAttributes.SCOPE_REQUEST));