User-Profile-Image
hankin
  • 5
  • Java
  • Kotlin
  • Spring
  • Web
  • SQL
  • MegaData
  • More
  • Experience
  • Enamiĝu al vi
  • 分类
    • Zuul
    • Zookeeper
    • XML
    • WebSocket
    • Web Notes
    • Web
    • Vue
    • Thymeleaf
    • SQL Server
    • SQL Notes
    • SQL
    • SpringSecurity
    • SpringMVC
    • SpringJPA
    • SpringCloud
    • SpringBoot
    • Spring Notes
    • Spring
    • Servlet
    • Ribbon
    • Redis
    • RabbitMQ
    • Python
    • PostgreSQL
    • OAuth2
    • NOSQL
    • Netty
    • MySQL
    • MyBatis
    • More
    • MinIO
    • MegaData
    • Maven
    • LoadBalancer
    • Kotlin Notes
    • Kotlin
    • Kafka
    • jQuery
    • JavaScript
    • Java Notes
    • Java
    • Hystrix
    • Git
    • Gateway
    • Freemarker
    • Feign
    • Eureka
    • ElasticSearch
    • Docker
    • Consul
    • Ajax
    • ActiveMQ
  • 页面
    • 归档
    • 摘要
    • 杂图
    • 问题随笔
  • 友链
    • Spring Cloud Alibaba
    • Spring Cloud Alibaba - 指南
    • Spring Cloud
    • Nacos
    • Docker
    • ElasticSearch
    • Kotlin中文版
    • Kotlin易百
    • KotlinWeb3
    • KotlinNhooo
    • 前端开源搜索
    • Ktorm ORM
    • Ktorm-KSP
    • Ebean ORM
    • Maven
    • 江南一点雨
    • 江南国际站
    • 设计模式
    • 熊猫大佬
    • java学习
    • kotlin函数查询
    • Istio 服务网格
    • istio
    • Ktor 异步 Web 框架
    • PostGis
    • kuangstudy
    • 源码地图
    • it教程吧
    • Arthas-JVM调优
    • Electron
    • bugstack虫洞栈
    • github大佬宝典
    • Sa-Token
    • 前端技术胖
    • bennyhuo-Kt大佬
    • Rickiyang博客
    • 李大辉大佬博客
    • KOIN
    • SQLDelight
    • Exposed-Kt-ORM
    • Javalin—Web 框架
    • http4k—HTTP包
    • 爱威尔大佬
    • 小土豆
    • 小胖哥安全框架
    • 负雪明烛刷题
    • Kotlin-FP-Arrow
    • Lua参考手册
    • 美团文章
    • Java 全栈知识体系
    • 尼恩架构师学习
    • 现代 JavaScript 教程
    • GO相关文档
    • Go学习导航
    • GoCN社区
    • GO极客兔兔-案例
    • 讯飞星火GPT
    • Hollis博客
    • PostgreSQL德哥
    • 优质博客推荐
    • 半兽人大佬
    • 系列教程
    • PostgreSQL文章
    • 云原生资料库
    • 并发博客大佬
Help?

Please contact us on our email for need any support

Support
    首页   ›   Spring   ›   SpringSecurity   ›   OAuth2   ›   正文
OAuth2

SpringSecurity—OAuth 2(九)第三方应用优化

2020-09-13 20:44:22
686  0 0

阅读完需:约 3 分钟

依旧是基于授权码模式改造:

SpringSecurity—OAuth 2(二)授权码模式


前面我们所写的第三方登录,我们在 Controller 中是这么定义的: (client-app 中的HelloController文件)

@GetMapping("/index.html")
    public String index2(String code , Model model){
        if(code!=null){
            System.out.println(code);
            //一个key对应多个value,通常我们会将多个value放到一个集合中
            MultiValueMap<String,String> map=new LinkedMultiValueMap();
            map.add("code",code);
            map.add("client_id","xjh");
            map.add("client_secret","123");
            map.add("redirect_uri","http://localhost:8082/index.html");
            map.add("grant_type","authorization_code");
            Map<String,String> resp = restTemplate.postForObject("http://localhost:8080/oauth/token", map, Map.class);
            System.out.println("resp="+resp);

            HttpHeaders headers=new HttpHeaders();
            headers.add("Authorization","Bearer"+resp.get("access_token"));
            HttpEntity<?> httpEntity=new HttpEntity<>(headers);
            ResponseEntity<String> responseEntity = restTemplate.exchange("http://localhost:8081/hello", HttpMethod.GET, httpEntity, String.class);
            model.addAttribute("msg",responseEntity.getBody());
        }
        return "index";
    }

我们可以封装优化一下:

首先我们来定义一个专门的类 TokenTask 用来解决 Token 的管理问题:

TokenTask

@Component
public class TokenTask {
    @Autowired
    RestTemplate restTemplate;
    public String access_token="";
    public String refresh_token="";

    /**
     * 刚拿到授权码去申请令牌
     */
    public  String getData(String code) {
        if ("".equals(access_token) && code != null) {
            MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
            map.add("code", code);
            map.add("client_id", "xjh");
            map.add("client_secret", "123");
            map.add("redirect_uri", "http://localhost:8082/index.html");
            map.add("grant_type", "authorization_code");
            Map<String, String> resp = restTemplate.postForObject("http://localhost:8080/oauth/token", map, Map.class);
            access_token = resp.get("access_token");
            refresh_token = resp.get("refresh_token");
        }
        return loadDataFromResServer();
    }

    /**
     * 通过令牌去申请资源
     * @return 返回资源的内容
     */
    private String loadDataFromResServer() {
        try {
            HttpHeaders headers=new HttpHeaders();
            headers.add("Authorization","Bearer"+access_token);
            HttpEntity<Object> httpEntity=new HttpEntity<>(headers);
            ResponseEntity<String> entity = restTemplate.exchange("http://localhost:8081/hello", HttpMethod.GET, httpEntity, String.class);
            return entity.getBody();
        }catch (Exception e){
            return "未加载";
        }

    }

    /**
     * 定时去刷新令牌
     */
    @Scheduled(cron = "0 55 0/1 * * ?")
    public void tokenTask(){
        MultiValueMap<String,String> map=new LinkedMultiValueMap<>();
        map.add("client_id","xjh");
        map.add("client_secret","123");
        map.add("grant_type","refresh_token");
        map.add("refresh_token",refresh_token);
        Map<String,String> resp = restTemplate.postForObject("http://localhost:8080/oauth/token", map, Map.class);
        access_token=resp.get("access_token");
        refresh_token=resp.get("refresh_token");
    }

}

这段代码没有技术难点,主要是逻辑上,我稍微解释一下:

  • 1. 首先在 getData 方法中,如果 access_token 为空字符串,并且 code 不为 null,表示这是刚刚拿到授权码的时候,准备去申请令牌了,令牌拿到之后,将 access_token 和 refresh_token 分别赋值给全局变量,然后调用 loadDataFromResServer 方法去资源服务器加载数据。
  • 2. 另外有一个 tokenTask 方法,这是一个定时任务,每隔 115 分钟去刷新一下access_token(access_token 有效期是 120 分钟)。

改造完成后,我们再去 HelloController 中略作调整:

    @Autowired
    TokenTask tokenTask;

    @GetMapping("/index.html")
    public String index(String code , Model model ){
        model.addAttribute("msg",tokenTask.getData(code));
        return "index";
    }

效果和之前的一样,但是不同的是这个页面这次再按F5刷新就不会出错了。

如本文“对您有用”,欢迎随意打赏作者,让我们坚持创作!

0 打赏
Enamiĝu al vi
不要为明天忧虑.因为明天自有明天的忧虑.一天的难处一天当就够了。
543文章 68评论 294点赞 593502浏览

随机文章
SpringCloud—GateWay(五)熔断、限流、重试
5年前
Java—ThreadPoolExecutor/ThreadPoolTaskExecutor 线程池技术提高系统吞吐量
5年前
Kotlin—日志的使用方法
4年前
MyBatis笔记10—resultType(返回类型)
5年前
Docker—网络(六)
5年前
博客统计
  • 日志总数:543 篇
  • 评论数目:68 条
  • 建站日期:2020-03-06
  • 运行天数:1927 天
  • 标签总数:23 个
  • 最后更新:2024-12-20
Copyright © 2025 网站备案号: 浙ICP备20017730号 身体没有灵魂是死的,信心没有行为也是死的。
主页
页面
  • 归档
  • 摘要
  • 杂图
  • 问题随笔
博主
Enamiĝu al vi
Enamiĝu al vi 管理员
To be, or not to be
543 文章 68 评论 593502 浏览
测试
测试
看板娘
赞赏作者

请通过微信、支付宝 APP 扫一扫

感谢您对作者的支持!

 支付宝 微信支付