精华内容
下载资源
问答
  • JustAuth
    2021-04-04 08:40:55

    JustAuth:第三方授权登录工具类库,脱离繁琐的第三方登录SDK,让登录变得So easy!

    转载:https://justauth.wiki/about.html

    转载理由:不错撒

     

    更多相关内容
  • Spring security 集成 JustAuth 实现第三方授权登录脚手架: 一、特性 : 此项目从 用户管理脚手架(UMS): | ) 项目中分离. 支持所有 justAuth 支持的第三方登录,登录后自动注册 或 绑定 或 创建临时用户(). 支持定时...
  • 本项目为 JustAuth开源项目( | )的demo。 交流 微信(备注:加群) 公众号 QQ群 JustAuth交流群 (230017570):专业交流该项目 开源总群 (190886500):各个开源项目的都有,也有博客建设等方面的朋友。
  • JustAuth.zip

    2021-05-21 10:43:22
    JustAuth,小而全而美的第三方登录开源组件。目前已支持Github、Gitee、微博、钉钉、百度、Coding、腾讯云开发者平台、OSChina、支付宝、QQ、微信、淘宝、Google、Facebook、抖音、领英、小米、微软、今日头条、...
  • justauth-spring-boot-starter-demo此 demo 主要演示 Spring Boot 如何使用 justauth-spring-boot-starter 集成 JustAuth快速开始1. 基础配置引用依赖<dependency> <groupId>...
  • justauth-spring-boot-starter Spring Boot 集成 JustAuth 的最佳实践~ JustAuth 脚手架 1. Demo 懒得看文档的,可以直接看demo 完整版 demo: 2. 更新日志 3. 快速开始 3.1. 基础配置 引用依赖 <groupId>...
  • justauth-spring-boot-starter-demo 此 demo 主要演示 Spring Boot 如何使用 justauth-spring-boot-starter 集成 JustAuth 快速开始 1. 基础配置 引用依赖 <groupId>com.xkcoding</groupId> <artifactId>justauth-...
  • JustAuth,如你所见,它仅仅是一个第三方授权登录的工具类库,它可以让我们脱离繁琐的第三方登录SDK,让登录变得So easy!项目开源地址:gitee | github特点废话不多说,就俩字:全:已集成十多家第三方平台(国内...
  • ?FCS-1000现场总线控制系统由操作站、控制站/采集站、HART协议网桥、FF协议网桥、分布式I/O模块、现场总线仪表所构成。并可下挂第三家厂家的仪表或设备,如PLC可编程逻辑控制器、、IMP/IMC采集器、XJ-100系列巡检...
  • 史上最全的整合第三方登录的工具,目前已支持Github、Gitee、微博、钉钉和百度、Coding、腾讯云开发者平台和OSChina等第三方平台的授权登录。 Login, so easy!
  • Spring security 集成 JustAuth 实现第三方授权登录脚手架: 一、特性 spring security 集成 JustAuth 实现第三方授权登录: 此项目从 用户管理脚手架(UMS):https://github.com/ZeroOrInfinity/UMS | ...

    Spring security 集成 JustAuth 实现第三方授权登录脚手架:

    一、特性

    spring security 集成 JustAuth 实现第三方授权登录 : 此项目从 用户管理脚手架(UMS):https://github.com/ZeroOrInfinity/UMS | https://gitee.com/pcore/UMS) 项目中分离.

    1. 支持所有 justAuth 支持的第三方登录,登录后自动注册 或 绑定.
    2. 支持定时刷新 accessToken 分布式定时任务,
    3. 支持第三方授权登录的用户信息表与 token 信息表的 redis 缓存功能.
    4. 支持第三方绑定与解绑及查询接口(top.dcenter.ums.security.core.oauth.repository.UsersConnectionRepository).

    二、maven

    <dependency>
        <groupId>top.dcenter</groupId>
        <artifactId>justAuth-spring-security-starter</artifactId>
        <version>1.0.1</version>
    </dependency>
    

    三、快速开始(Quick Start)

    1. 添加依赖:

    <dependency>
        <groupId>top.dcenter</groupId>
        <artifactId>justAuth-spring-security-starter</artifactId>
        <version>1.0.1</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.3.4.RELEASE</version>
    </dependency>
    
    <!-- mysql -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.21</version>
    </dependency>
    

    2. config:

    server:
      port: 9090
    
    spring:
      profiles:
        active: dev
      # mysql
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/ums?useSSL=false&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai
        username: root
        password: 123456
    
      # session 简单配置
      session:
        # session 存储模式设置, 要导入相应的 spring-session 类的依赖, 默认为 none, 分布式应用把 session 放入 redis 等中间件
        store-type: none
        # session 过期时间
        timeout: PT300s
    
    # ums core
    ums:
      # ================ 第三方授权登录相关配置 ================
      oauth:
        # 是否支持第三方授权登录功能, 默认: true
        enabled: true
        # 抑制反射警告, 支持 JDK11, 默认: false , 在确认 WARNING: An illegal reflective access operation has occurred 安全后, 可以打开此设置, 可以抑制反射警告.
        suppress-reflect-warning: true
        # 第三方服务商: providerId, 支持所有 JustAuth 支持的第三方授权登录, 目前有 32 家第三方授权登录
        github:
          # 根据是否有设置 clientId 来动态加载相应 JustAuth 的 AuthXxxRequest
          client-id: 4d4ee00e82f669f2ea8d
          client-secret: 953ddbe871a08d6924053531e89ecc01d87195a8
        gitee:
          client-id: dcc38c801ee88f43cfc1d5c52ec579751c12610c37b87428331bd6694056648e
          client-secret: e60a110a2f6e7c930c2d416f802bec6061e19bfa0ceb0df9f6b182b05d8f5a58
        # 第三方登录授权登录 url 前缀, 不包含 ServletContextPath,默认为 /auth2/authorization.
        auth-login-url-prefix: /auth2/authorization
        # 第三方登录回调处理 url 前缀 ,也就是 RedirectUrl 的前缀, 不包含 ServletContextPath,默认为 /auth2/login.
        redirect-url-prefix: /auth2/login
        # 第三方登录回调的域名, 例如:http://localhost:9090 默认为 "http://127.0.0.1",
        # redirectUrl 直接由 {domain}/{servletContextPath}/{redirectUrlPrefix}/{providerId}(ums.oauth.[qq/gitee/weibo])组成
        domain: http://localhost:9090
        # 第三方授权登录成功后的默认权限, 多个权限用逗号分开, 默认为: "ROLE_USER"
        default-authorities: ROLE_USER
    
        # 用于 JustAuth 的代理(HttpClient)设置
        proxy:      
          # 用于国内代理(HttpClient)超时, 默认 PT3S
          timeout: PT3S
          # 用于国外网站代理(HttpClient)超时, 默认 PT15S
          foreign-timeout: PT150S  
    ---
    spring:
      profiles: dev
      mvc:
        throw-exception-if-no-handler-found: true
    
    #debug: true
    
    server:
      port: 9090
      servlet:
        context-path: /demo
    

    3. 必须实现 UmsUserDetailsService 接口:

    UserDetailsServiceImpl.java

    import lombok.extern.slf4j.Slf4j;
    import me.zhyd.oauth.model.AuthUser;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.AuthorityUtils;
    import org.springframework.security.core.userdetails.User;
    import org.springframework.security.core.userdetails.UserCache;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.stereotype.Service;
    import top.dcenter.ums.security.core.oauth.enums.ErrorCodeEnum;
    import top.dcenter.ums.security.core.oauth.exception.RegisterUserFailureException;
    import top.dcenter.ums.security.core.oauth.exception.UserNotExistException;
    import top.dcenter.ums.security.core.oauth.service.UmsUserDetailsService;
    
    import java.util.List;
    
    /**
     *  用户密码与手机短信登录与注册服务:<br><br>
     *  1. 用于第三方登录与手机短信登录逻辑。<br><br>
     *  2. 用于用户密码登录逻辑。<br><br>
     *  3. 用户注册逻辑。<br><br>
     * @author YongWu zheng
     * @version V1.0  Created by 2020/9/20 11:06
     */
    @Service
    @Slf4j
    public class UserDetailsServiceImpl implements UmsUserDetailsService {
    
        @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
        @Autowired(required = false)
        private UserCache userCache;
        /**
         * 用于密码加解密
         */
        @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
        @Autowired
        private PasswordEncoder passwordEncoder;
    
        @SuppressWarnings("AlibabaUndefineMagicConstant")
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    
            try
            {
                // 从缓存中查询用户信息:
                // 从缓存中查询用户信息
                if (this.userCache != null)
                {
                    UserDetails userDetails = this.userCache.getUserFromCache(username);
                    if (userDetails != null)
                    {
                        return userDetails;
                    }
                }
                // 根据用户名获取用户信息
    
                // 获取用户信息逻辑。。。
                // ...
    
                // 示例:只是从用户登录日志表中提取的信息,
                log.info("Demo ======>: 登录用户名:{}, 登录成功", username);
                return new User(username,
                                passwordEncoder.encode("admin"),
                                true,
                                true,
                                true,
                                true,
                                AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_VISIT, ROLE_USER"));
    
            }
            catch (Exception e)
            {
                String msg = String.format("Demo ======>: 登录用户名:%s, 登录失败: %s", username, e.getMessage());
                log.error(msg, e);
                throw new UserNotExistException(ErrorCodeEnum.QUERY_USER_INFO_ERROR, e, username);
            }
        }
    
        @Override
        public UserDetails registerUser(AuthUser authUser, String username, String defaultAuthority) throws RegisterUserFailureException {
    
            // 第三方授权登录不需要密码, 这里随便设置的, 生成环境按自己的逻辑
            String encodedPassword = passwordEncoder.encode(authUser.getUuid());
    
            List<GrantedAuthority> grantedAuthorities = AuthorityUtils.commaSeparatedStringToAuthorityList(defaultAuthority);
    
            // ... 用户注册逻辑
    
            log.info("Demo ======>: 用户名:{}, 注册成功", username);
    
            // @formatter:off
            UserDetails user = User.builder()
                                   .username(username)
                                   .password(encodedPassword)
                                   .disabled(false)
                                   .accountExpired(false)
                                   .accountLocked(false)
                                   .credentialsExpired(false)
                                   .authorities(grantedAuthorities)
                                   .build();
            // @formatter:off
    
            // 把用户信息存入缓存
            if (userCache != null)
            {
                userCache.putUserInCache(user);
            }
    
            return user;
        }
    
        @Override
        public UserDetails loadUserByUserId(String userId) throws UsernameNotFoundException {
            UserDetails userDetails = loadUserByUsername(userId);
            User.withUserDetails(userDetails);
            return User.withUserDetails(userDetails).build();
        }
    
        @Override
        public List<Boolean> existedByUserIds(String... userIds) throws UsernameNotFoundException {
            // ... 在本地账户上查询 userIds 是否已被使用
            return List.of(true, false, false);
        }
    
    }
    
    

    4. 必须添加 Auth2AutoConfigurer 到 HttpSecurity

    WebSecurityConfig.java

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.HttpMethod;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.crypto.factory.PasswordEncoderFactories;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import top.dcenter.ums.security.core.oauth.config.Auth2AutoConfigurer;
    import top.dcenter.ums.security.core.oauth.properties.Auth2Properties;
    
    /**
     * web security config
     * @author YongWu zheng
     * @version V2.0  Created by 2020/10/18 22:39
     */
    @Configuration
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Autowired
        private Auth2AutoConfigurer auth2AutoConfigurer;
        @Autowired
        private Auth2Properties auth2Properties;
    
        @Bean
        public PasswordEncoder passwordEncoder() {
            /*
                默认为 BCryptPasswordEncoder 的实现了添加随机 salt 算法,并且能从hash后的字符串中获取 salt 进行原始密码与hash后的密码的对比
                支持格式:
                {bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
                {noop}password
                {pbkdf2}5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc
                {scrypt}$e0801$8bWJaSu2IKSn9Z9kM+TPXfOc/9bdYSrN1oD9qfVThWEwdRTnO7re7Ei+fUZRJ68k9lTyuTeUp4of4g24hHnazw==$OAOec05+bXxvuu/1qZ6NUR+xQYvYv7BeL1QxwRpY5Pc=
                {sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0
             */
            return PasswordEncoderFactories.createDelegatingPasswordEncoder();
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
    
            http.formLogin()
                .loginPage("/login.html")
                .defaultSuccessUrl("/index.html");
            http.logout().logoutSuccessUrl("/login.html");
    
            // ========= start: 使用 justAuth-spring-security-starter 必须步骤 ========= 
            // 添加 Auth2AutoConfigurer 使 OAuth2(justAuth) login 生效.
            http.apply(this.auth2AutoConfigurer);
    
            // 放行第三方登录入口地址与第三方登录回调地址
            // @formatter:off
            http.authorizeRequests()
                    .antMatchers(HttpMethod.GET,
                                 auth2Properties.getRedirectUrlPrefix() + "/*",
                                 auth2Properties.getAuthLoginUrlPrefix() + "/*")
                    .permitAll();
            // @formatter:on
            // ========= end: 使用 justAuth-spring-security-starter 必须步骤 ========= 
    
            http.authorizeRequests().anyRequest().permitAll();
        }
    }
    

    4. 前端页面 :

    login.html: 放在 classpath:/static

    <!DOCTYPE html>
    <html">
    <head>
        <meta charset="UTF-8">
        <title>登录</title>
    
    </head>
    <body>
    <h2>登录页面</h2>
    <h3>社交登录</h3>
    <a href="/demo/auth2/authorization/gitee">gitee登录</a>
    <a href="/demo/auth2/authorization/github">github登录</a>
    <a href="/demo/auth2/authorization/qq">qq登录</a>
    </body>
    </html>
    

    index.html: 放在 classpath:/static

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
    hello world!<br>
        <form action="/demo/logout?logout" method="post">
            <input type="submit" value="退出登录post"/>
        </form>
    
    <br>
    <br>
    <a href="/demo/auth2/authorization/gitee">gitee登录</a>
    <a href="/demo/auth2/authorization/github">github登录</a>
    <a href="/demo/auth2/authorization/qq">qq登录</a>
    </body>
    </html>
    

    5. 访问前端页面


    四、使用说明:

    1. 引入依赖

    <dependency>
        <groupId>top.dcenter</groupId>
        <artifactId>justAuth-spring-security-starter</artifactId>
        <version>1.0.1</version>
    </dependency>
    

    2. 必须实现的接口

    3. 必须添加 Auth2AutoConfigurer 到 HttpSecurity

    @Configuration
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Autowired
        private Auth2AutoConfigurer auth2AutoConfigurer;
        @Autowired
        private Auth2Properties auth2Properties;
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
    
            // ========= start: 使用 justAuth-spring-security-starter 必须步骤 ========= 
            // 添加 Auth2AutoConfigurer 使 OAuth2(justAuth) login 生效.
            http.apply(this.auth2AutoConfigurer);
    
            // 放行第三方登录入口地址与第三方登录回调地址
            // @formatter:off
            http.authorizeRequests()
                    .antMatchers(HttpMethod.GET,
                                 auth2Properties.getRedirectUrlPrefix() + "/*",
                                 auth2Properties.getAuthLoginUrlPrefix() + "/*")
                    .permitAll();
            // @formatter:on
            // ========= end: 使用 justAuth-spring-security-starter 必须步骤 ========= 
    
        }
    }
    

    4. 属性配置

    • justAuth-spring-security-starter 大部分功能实现都是通过配置文件设置属性来完成的, 详细属性配置请查看五、属性配置列表.

    五、时序图(Sequence Diagram): 随着版本迭代会有出入

    第三方授权登录


    六、属性配置列表

    OAuth2 / refreshToken 定时任务 / JustAuth 配置属性

    属性类型默认值描述可选项
    ums.oauth.enabledBooleantrue是否支持第三方授权登录功能, 默认: truetrue/false
    ums.oauth.domainStringhttp://127.0.0.1第三方登录回调的域名, 例如:https://localhost 默认为 “http://127.0.0.1”, redirectUrl 直接由 {domain}/{servletContextPath}/{redirectUrlPrefix}/{providerId}(ums.oauth.[qq/gitee/weibo])组成
    ums.oauth.redirectUrlPrefixString/oauth/login第三方登录回调处理 url 前缀 ,也就是 RedirectUrl 的前缀, 不包含 ServletContextPahth,默认为 /oauth/login
    ums.oauth.authLoginUrlPrefixString/oauth/authorization第三方登录授权登录 url 前缀, 不包含 ServletContextPath,默认为 /oauth/authorization
    ums.oauth.defaultAuthoritiesStringROLE_USER第三方授权登录成功后的默认权限, 多个权限用逗号分开, 默认为: “ROLE_USER”
    ums.oauth.suppressReflectWarningBooleanfalse抑制反射警告, 支持 JDK11, 默认: false , 在确认 WARNING: An illegal reflective access operation has occurred 安全后, 可以打开此设置, 可以抑制反射警告.true/false
    refreshToken 定时任务
    ums.oauth.refreshTokenJobCronString0 * 2 * * ?A cron-like expression.
    0 * 2 * * ? 分别对应: second/minute/hour/day of month/month/day of week

    默认为: “0 * 2 * * ?”, 凌晨 2 点启动定时任务, 支持分布式(分布式 IOC 容器中必须有 RedisConnectionFactory, 也就是说, 是否分布式执行依据 IOC 容器中是否有 RedisConnectionFactory)
    ums.oauth.enableRefreshTokenJobBooleanfalse是否支持定时刷新 AccessToken 定时任务. 默认: false. 支持分布式(分布式 IOC 容器中必须有 RedisConnectionFactory, 也就是说, 是否分布式执行依据 IOC 容器中是否有 RedisConnectionFactory)true/false
    ums.oauth.batchCountInteger1000定时刷新 accessToken 任务时, 批处理数据库的记录数. 注意: 分布式应用时, 此配置不同服务器配置必须是一样的. batchCount 大小需要根据实际生产环境进行优化
    ums.oauth.remainingExpireInInteger24accessToken 的剩余有效期内进行刷新 accessToken, 默认: 24, 单位: 小时. 注意: 需要根据实际生产环境进行优化
    justAuth
    ums.oauth.justAuth.ignoreCheckStateBooleanfalse忽略校验 state 参数,默认不开启。当 ignoreCheckState 为 true 时, me.zhyd.oauth.request.AuthDefaultRequest.login(AuthCallback) 将不会校验 state 的合法性。
    使用场景:当且仅当使用自实现 state 校验逻辑时开启
    以下场景使用方案仅作参考: 1. 授权、登录为同端,并且全部使用 JustAuth 实现时,该值建议设为 false; 2. 授权和登录为不同端实现时,比如前端页面拼装 authorizeUrl,并且前端自行对state进行校验, 后端只负责使用code获取用户信息时,该值建议设为 true; 如非特殊需要,不建议开启这个配置
    该方案主要为了解决以下类似场景的问题:
    true/false
    ums.oauth.justAuth.timeoutDurationPT180S默认 state 缓存过期时间:3分钟(PT180S) 鉴于授权过程中,根据个人的操作习惯,或者授权平台的不同(google等),每个授权流程的耗时也有差异,不过单个授权流程一般不会太长 本缓存工具默认的过期时间设置为3分钟,即程序默认认为3分钟内的授权有效,超过3分钟则默认失效,失效后删除
    ums.oauth.justAuth.cacheTypeStateCacheTypeSESSIONJustAuth state 缓存类型, 默认 sessionDEFAULT/SESSION/REDIS
    ums.oauth.justAuth.cacheKeyPrefixStringJUST_AUTH:JustAuth state 缓存 key 前缀
    ums.oauth.justAuth.scopesList支持自定义授权平台的 scope 内容
    proxy
    ums.oauth.proxy.enableBooleanfalse是否支持代理, 默认为: false. 当为 false 时, 其他属性都失效.true/false
    ums.oauth.proxy.proxyProxy.TypeHTTP针对国外服务可以单独设置代理类型, 默认 Proxy.Type.HTTPHTTP/DIRECT/SOCKS
    ums.oauth.proxy.hostnameString代理 host, enable = true 时生效.
    ums.oauth.proxy.portInteger代理端口, enable = true 时生效.
    ums.oauth.proxy.timeoutDurationPT3S代理超时, 默认 PT3S
    ums.oauth.proxy.foreignTimeoutDurationPT15S用于国外网站代理超时, 默认 PT15S
    github
    ums.oauth.github.providerIdStringgithub第三方服务商 id
    ums.oauth.github.clientIdStringclient Id
    ums.oauth.github.clientSecretStringclient Secret
    weibo
    ums.oauth.weibo.providerIdStringweibo第三方服务商 id
    ums.oauth.weibo.clientIdStringclient Id
    ums.oauth.weibo.clientSecretStringclient Secret
    gitee
    ums.oauth.gitee.providerIdStringgitee第三方服务商 id
    ums.oauth.gitee.clientIdStringclient Id
    ums.oauth.gitee.clientSecretStringclient Secret
    dingtalk
    ums.oauth.dingtalk.providerIdStringdingtalk第三方服务商 id
    ums.oauth.dingtalk.clientIdStringclient Id
    ums.oauth.dingtalk.clientSecretStringclient Secret
    baidu
    ums.oauth.baidu.providerIdStringbaidu第三方服务商 id
    ums.oauth.baidu.clientIdStringclient Id
    ums.oauth.baidu.clientSecretStringclient Secret
    csdn: 注意:该平台已不支持
    ums.oauth.csdn.providerIdStringcsdn第三方服务商 id
    ums.oauth.csdn.clientIdStringclient Id
    ums.oauth.csdn.clientSecretStringclient Secret
    coding
    ums.oauth.coding.providerIdStringcoding第三方服务商 id
    ums.oauth.coding.clientIdStringclient Id
    ums.oauth.coding.clientSecretStringclient Secret
    ums.oauth.coding.codingGroupNameString使用 Coding 登录时,需要传该值。
    团队域名前缀,比如以“ https://justauth.coding.net/ ”为例,``codingGroupName = justauth`
    oschina
    ums.oauth.oschina.providerIdStringoschina第三方服务商 id
    ums.oauth.oschina.clientIdStringclient Id
    ums.oauth.oschina.clientSecretStringclient Secret
    alipay
    ums.oauth.alipay.providerIdStringalipay第三方服务商 id
    ums.oauth.alipay.clientIdStringclient Id
    ums.oauth.alipay.clientSecretStringclient Secret
    ums.oauth.alipay.alipayPublicKeyString支付宝公钥:当选择支付宝登录时,该值可用 对应“RSA2(SHA256)密钥”中的“支付宝公钥”
    qq
    ums.oauth.qq.providerIdStringqq第三方服务商 id
    ums.oauth.qq.clientIdStringclient Id
    ums.oauth.qq.clientSecretStringclient Secret
    ums.oauth.qq.unionIdString是否需要申请 unionId,默认: false. 目前只针对qq登录 注:qq授权登录时,获取 unionId 需要单独发送邮件申请权限。如果个人开发者账号中申请了该权限,可以将该值置为true,在获取openId时就会同步获取unionId 参考链接:http://wiki.connect.qq.com/unionid%E4%BB%8B%E7%BB%8D
    wechatOpen
    ums.oauth.wechatOpen.providerIdStringwechatOpen第三方服务商 id
    ums.oauth.wechatOpen.clientIdStringclient Id
    ums.oauth.wechatOpen.clientSecretStringclient Secret
    wechatMp
    ums.oauth.wechatMp.providerIdStringwechatMp第三方服务商 id
    ums.oauth.wechatMp.clientIdStringclient Id
    ums.oauth.wechatMp.clientSecretStringclient Secret
    taobao
    ums.oauth.taobao.providerIdStringtaobao第三方服务商 id
    ums.oauth.taobao.clientIdStringclient Id
    ums.oauth.taobao.clientSecretStringclient Secret
    google
    ums.oauth.google.providerIdStringgoogle第三方服务商 id
    ums.oauth.google.clientIdStringclient Id
    ums.oauth.google.clientSecretStringclient Secret
    facebook
    ums.oauth.facebook.providerIdStringfacebook第三方服务商 id
    ums.oauth.facebook.clientIdStringclient Id
    ums.oauth.facebook.clientSecretStringclient Secret
    github
    ums.oauth.github.providerIdStringgithub第三方服务商 id
    ums.oauth.github.clientIdStringclient Id
    ums.oauth.github.clientSecretStringclient Secret
    douyin
    ums.oauth.douyin.providerIdStringdouyin第三方服务商 id
    ums.oauth.douyin.clientIdStringclient Id
    ums.oauth.douyin.clientSecretStringclient Secret
    linkedin
    ums.oauth.linkedin.providerIdStringlinkedin第三方服务商 id
    ums.oauth.linkedin.clientIdStringclient Id
    ums.oauth.linkedin.clientSecretStringclient Secret
    microsoft
    ums.oauth.microsoft.providerIdStringmicrosoft第三方服务商 id
    ums.oauth.microsoft.clientIdStringclient Id
    ums.oauth.microsoft.clientSecretStringclient Secret
    mi
    ums.oauth.mi.providerIdStringmi第三方服务商 id
    ums.oauth.mi.clientIdStringclient Id
    ums.oauth.mi.clientSecretStringclient Secret
    toutiao
    ums.oauth.toutiao.providerIdStringtoutiao第三方服务商 id
    ums.oauth.toutiao.clientIdStringclient Id
    ums.oauth.toutiao.clientSecretStringclient Secret
    teambition
    ums.oauth.teambition.providerIdStringteambition第三方服务商 id
    ums.oauth.teambition.clientIdStringclient Id
    ums.oauth.teambition.clientSecretStringclient Secret
    renren
    ums.oauth.renren.providerIdStringrenren第三方服务商 id
    ums.oauth.renren.clientIdStringclient Id
    ums.oauth.renren.clientSecretStringclient Secret
    pinterest
    ums.oauth.pinterest.providerIdStringpinterest第三方服务商 id
    ums.oauth.pinterest.clientIdStringclient Id
    ums.oauth.pinterest.clientSecretStringclient Secret
    stackOverflow
    ums.oauth.stackOverflow.providerIdStringstackOverflow第三方服务商 id
    ums.oauth.stackOverflow.clientIdStringclient Id
    ums.oauth.stackOverflow.clientSecretStringclient Secret
    ums.oauth.stackOverflow.stackOverflowKeyStringStack Overflow Key
    huawei
    ums.oauth.huawei.providerIdStringhuawei第三方服务商 id
    ums.oauth.huawei.clientIdStringclient Id
    ums.oauth.huawei.clientSecretStringclient Secret
    wechatEnterprise
    ums.oauth.wechatEnterprise.providerIdStringwechatEnterprise第三方服务商 id
    ums.oauth.wechatEnterprise.clientIdStringclient Id
    ums.oauth.wechatEnterprise.clientSecretStringclient Secret
    ums.oauth.wechatEnterprise.agentIdString企业微信,授权方的网页应用ID
    kujiale
    ums.oauth.kujiale.providerIdStringkujiale第三方服务商 id
    ums.oauth.kujiale.clientIdStringclient Id
    ums.oauth.kujiale.clientSecretStringclient Secret
    gitlab
    ums.oauth.gitlab.providerIdStringgitlab第三方服务商 id
    ums.oauth.gitlab.clientIdStringclient Id
    ums.oauth.gitlab.clientSecretStringclient Secret
    meituan
    ums.oauth.meituan.providerIdStringmeituan第三方服务商 id
    ums.oauth.meituan.clientIdStringclient Id
    ums.oauth.meituan.clientSecretStringclient Secret
    eleme
    ums.oauth.eleme.providerIdStringeleme第三方服务商 id
    ums.oauth.eleme.clientIdStringclient Id
    ums.oauth.eleme.clientSecretStringclient Secret
    twitter
    ums.oauth.twitter.providerIdStringtwitter第三方服务商 id
    ums.oauth.twitter.clientIdStringclient Id
    ums.oauth.twitter.clientSecretStringclient Secret
    feishu: 注意:该平台暂时存在问题,请不要使用。待修复完成后会重新发版by yadong.zhang
    ums.oauth.feishu.providerIdStringfeishu第三方服务商 id
    ums.oauth.feishu.clientIdStringclient Id
    ums.oauth.feishu.clientSecretStringclient Secret
    jd
    ums.oauth.jd.providerIdStringjd第三方服务商 id
    ums.oauth.jd.clientIdStringclient Id
    ums.oauth.jd.clientSecretStringclient Secret
    aliyun
    ums.oauth.aliyun.providerIdStringaliyun第三方服务商 id
    ums.oauth.aliyun.clientIdStringclient Id
    ums.oauth.aliyun.clientSecretStringclient Secret

    线程池属性

    属性类型默认值描述可选项
    accessTokenRefreshJob
    ums.executor.accessTokenRefreshJob.openBooleanfalse是否支持自动刷新 accessTokentrue/false
    ums.executor.accessTokenRefreshJob.corePoolSizeInteger0线程池中空闲时保留的线程数, 默认: 0
    ums.executor.accessTokenRefreshJob.keepAliveTimeInteger10keep alive time, 默认: 10
    ums.executor.accessTokenRefreshJob.timeUnitTimeUnitTimeUnit.MILLISECONDSkeepAliveTime 时间单位, 默认: 毫秒MILLISECONDS/MICROSECONDS/MILLISECONDS/SECONDS/MINUTES/HOURS/DAYS
    ums.executor.accessTokenRefreshJob.poolNameStringaccessTokenJob线程池名称, 默认: accessTokenJob
    ums.executor.accessTokenRefreshJob.rejectedExecutionHandlerPolicyRejectedExecutionHandlerPolicyABORT拒绝策略, 默认: ABORTABORT/CALLER_RUNS/DISCARD_OLDEST/DISCARD
    ums.executor.accessTokenRefreshJob.executorShutdownTimeoutDurationPT10S线程池关闭过程的超时时间, 默认: PT10S
    refreshToken
    ums.executor.refreshToken.corePoolSizeInteger0线程池中空闲时保留的线程数, 默认: 0
    ums.executor.refreshToken.maximumPoolSizeIntegerRuntime.getRuntime().availableProcessors()最大线程数, 默认: 本机核心数
    ums.executor.refreshToken.keepAliveTimeInteger5keep alive time, 默认: 5
    ums.executor.refreshToken.timeUnitTimeUnitTimeUnit.SECONDSkeepAliveTime 时间单位, 默认: 秒MILLISECONDS/MICROSECONDS/MILLISECONDS/SECONDS/MINUTES/HOURS/DAYS
    ums.executor.refreshToken.blockingQueueCapacityIntegermaximumPoolSize * 2blocking queue capacity, 默认: maximumPoolSize * 2
    ums.executor.refreshToken.poolNameStringrefreshToken线程池名称, 默认: refreshToken
    ums.executor.refreshToken.rejectedExecutionHandlerPolicyRejectedExecutionHandlerPolicyCALLER_RUNS拒绝策略, 默认: CALLER_RUNS 注意: 一般情况下不要更改默认设置, 没有实现 RefreshToken 逻辑被拒绝执行后的处理逻辑, 除非自己实现RefreshTokenJob.refreshTokenJob() 对 RefreshToken 逻辑被拒绝执行后的处理逻辑.ABORT/CALLER_RUNS/DISCARD_OLDEST/DISCARD
    ums.executor.refreshToken.executorShutdownTimeoutDurationPT10S线程池关闭过程的超时时间, 默认: PT10S
    updateConnection
    ums.executor.updateConnection.corePoolSizeInteger5线程池中空闲时保留的线程数, 默认: 5
    ums.executor.updateConnection.maximumPoolSizeIntegerRuntime.getRuntime().availableProcessors()最大线程数, 默认: 本机核心数
    ums.executor.updateConnection.keepAliveTimeInteger10keep alive time, 默认: 10
    ums.executor.updateConnection.timeUnitTimeUnitTimeUnit.SECONDSkeepAliveTime 时间单位, 默认: 秒MILLISECONDS/MICROSECONDS/MILLISECONDS/SECONDS/MINUTES/HOURS/DAYS
    ums.executor.updateConnection.blockingQueueCapacityIntegermaximumPoolSize * 2blocking queue capacity, 默认: maximumPoolSize * 2
    ums.executor.updateConnection.poolNameStringupdateConnection线程池名称, 默认: updateConnection
    ums.executor.updateConnection.rejectedExecutionHandlerPolicyRejectedExecutionHandlerPolicyCALLER_RUNS拒绝策略, 默认: CALLER_RUNS 注意: 一般情况下不要更改默认设置, 除非自己实现Auth2LoginAuthenticationProvider更新逻辑; 改成 ABORT 也支持, 默认实现 Auth2LoginAuthenticationProvider 是异步更新被拒绝执行后, 会执行同步更新.ABORT/CALLER_RUNS/DISCARD_OLDEST/DISCARD
    ums.executor.updateConnection.executorShutdownTimeoutDurationPT10S线程池关闭过程的超时时间, 默认: PT10S

    对第三方授权登录用户信息与 token 的持久化(jdbc)数据是否缓存到 redis 的配置

    属性类型默认值描述可选项
    ums.cache.redis.openBooleanfalseRedis cache is open, 默认 falsetrue/false
    ums.cache.redis.useIocRedisConnectionFactoryBooleanfalse是否使用 spring IOC 容器中的 RedisConnectionFactory, 默认: false. 如果使用 spring IOC 容器中的 RedisConnectionFactory,则要注意 cache.database-index 要与 spring.redis.database 一样true/false
    cache
    ums.cache.redis.cache.databaseIndexInteger0redis cache 存放的 database index, 默认: 0
    ums.cache.redis.cache.defaultExpireTimeDurationPT200S设置缓存管理器管理的缓存的默认过期时间, 默认: 200, 单位: 秒
    ums.cache.redis.cache.entryTtlDurationPT180Scache ttl 。使用 0 声明一个永久的缓存。 默认: 180, 单位: 秒 取缓存时间的 20% 作为动态的随机变量上下浮动, 防止同时缓存失效而缓存击穿
    ums.cache.redis.cache.cacheNamesSetNames of the default caches to consider for caching operations defined in the annotated class.

    第三方授权登录用户信息表 user_connection sql 配置

    属性类型默认值描述可选项
    第三方登录相关
    ums.repository.userIdParamNameStringuserId第三方登录用户注册时: 用户唯一 ID 字段名称, 默认为 userId
    ums.repository.passwordParamNameStringpassword第三方登录用户注册时: 密码 字段名称, 默认为 password
    ums.repository.providerIdParamNameStringproviderId第三方录用户注册时: 服务商 providerId 字段名称, 默认为 providerId
    ums.repository.providerUserIdParamNameStringproviderUserId第三方登录用户注册时: 在服务商那的用户唯一ID providerUserId 字段名称, 默认为 providerUserId
    ums.repository.avatarUrlParamNameStringavatarUrl第三方登录用户注册时: 用户头像 avatarUrl 字段名称, 默认为 avatarUrl
    自定义第三方登录用户表及相关 CURD 语句
    ums.repository.tableNameStringuser_connection第三方登录用户数据库表名称,
    ums.repository.userIdColumnNameStringuserId第三方登录用户数据库用户表用户唯一 ID 字段名称, 默认为 userId
    ums.repository.providerIdColumnNameStringproviderId第三方登录用户数据库用户表服务商 providerId 字段名称, 默认为 providerId
    ums.repository.providerUserIdColumnNameStringproviderUserId第三方登录用户数据库用户表服务商用户 providerUserId 字段名称, 默认为 providerUserId
    ums.repository.rankColumnNameStringrank第三方登录用户数据库用户表 rank 字段名称, 默认为 rank。 注意:因为 MySQL 8.0 版本 rank 是个关键字。一定要用 ` 包裹。
    ums.repository.displayNameColumnNameStringdisplayName第三方登录用户数据库用户表用户显示名称 displayName 字段名称, 默认为 displayName
    ums.repository.profileUrlColumnNameStringprofileUrl第三方登录用户数据库用户表用户主页 profileUrl 字段名称, 默认为 profileUrl
    ums.repository.imageUrlColumnNameStringimageUrl第三方登录用户数据库用户表用户头像 imageUrl 字段名称, 默认为 imageUrl
    ums.repository.accessTokenColumnNameStringaccessToken第三方登录用户数据库用户表用户 accessToken 字段名称, 默认为 accessToken
    ums.repository.tokenIdColumnNameStringtokenId第三方登录用户数据库用户表用户 tokenId 字段名称, 默认为 tokenId
    ums.repository.refreshTokenColumnNameStringrefreshToken第三方登录用户数据库用户表用户显 refreshToken 字段名称, 默认为 refreshToken
    ums.repository.expireTimeColumnNameStringexpireTime第三方登录用户数据库用户表用户过期时间 expireTime 字段名称, 默认为 expireTime
    ums.repository.creatUserConnectionTableSqlString“CREATE TABLE %s (%s varchar(255) NOT NULL, %s varchar(255) NOT NULL, %s varchar(255) NOT NULL, %s int NOT NULL, %s varchar(255), %s varchar(512), %s varchar(512), %s varchar(512) NOT NULL, %s varchar(512), %s varchar(512), %s bigint, PRIMARY KEY (%s, %s, %s), unique KEY idx_userId_providerId_rank(%s, %s, %s), KEY idx_providerId_providerUserId_rank (%s, %s, %s)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;”第三方登录用户数据库用户表创建语句。 修改第三方登录用户数据库用户表创建语句时,要注意:修改字段名称可以直接修改上面的字段名称即可,不用修改建表语句,不可以减少字段,但可以另外增加字段。 用户需要对第三方登录的用户表与 curd 的 sql 语句结构进行更改时, 必须实现对应的 UsersConnectionRepositoryFactory, 如果需要,请实现 UsersConnectionRepositoryFactory,可以参考 Auth2JdbcUsersConnectionRepositoryFactory。 注意: sql 语句中的 %s 必须写上,且 %s 的顺序必须与后面的字段名称所对应的含义对应 : tableName、 userIdColumnName、 providerIdColumnName、 providerUserIdColumnName、 rankColumnName、 displayNameColumnName、 profileUrlColumnName、 imageUrlColumnName、 accessTokenColumnName、 tokenIdColumnName、 refreshTokenColumnName、 expireTimeColumnName、 userIdColumnName、 providerIdColumnName、 providerUserIdColumnName、 userIdColumnName、 providerIdColumnName、 rankColumnName、 providerIdColumnName、 providerUserIdColumnName、 rankColumnName、
    ums.repository.queryUserConnectionTableExistSqlStringSELECT COUNT(1) FROM information_schema.tables WHERE table_schema=’%s’ AND table_name = ‘%s’第三方登录用户数据库用户表查询 userIds 的查询语句。 注意: sql 语句中的 %s 必须写上,问号必须与指定的 %s 相对应,%s按顺序会用对应的 : databaseName、 tableName
    ums.repository.findUserIdsWithConnectionSqlStringselect %s from %s where %s = ? and %s = ?第三方登录用户数据库用户表查询 userIds 的查询语句。 注意: sql 语句中的 %s 必须写上,问号必须与指定的 %s 相对应,%s按顺序会用对应的 : userIdColumnName、 tableName、 providerIdColumnName、 providerUserIdColumnName
    ums.repository.findUserIdsConnectedToSqlStringselect %s from %S where %s = :%s and %s in (:%s)通过第三方服务提供商提供的 providerId 与 providerUserIds 从数据库用户表查询 userIds 的查询语句。 注意: sql 语句中的 %s 必须写上,问号必须与指定的 %s 相对应,%s按顺序会用对应的 : userIdColumnName、 tableName、 providerIdColumnName、 providerUserIdColumnName
    ums.repository.selectFromUserConnectionSqlStringselect %s, %s, %s, %s, %s, %s, %s, %s, %s, %s from %s通过第三方服务提供商提供的 providerId 与 providerUserIds 从数据库用户表查询 userIds 的查询语句。 注意: sql 语句中的 %s 必须写上,问号必须与指定的 %s 相对应, %s按顺序会用对应的 : userIdColumnName、 providerIdColumnName、 providerUserIdColumnName、 displayNameColumnName、 profileUrlColumnName、 imageUrlColumnName、 accessTokenColumnName、 tokenIdColumnName、 refreshTokenColumnName、 expireTimeColumnName、 tableName
    ums.repository.updateConnectionSqlStringupdate %s set %s = ?, %s = ?, %s = ?, %s = ?, %s = ?, %s = ?, %s = ? where %s = ? and %s = ? and %s = ?第三方登录用户数据库用户表更新语句。 注意: sql 语句中的 %s 必须写上,问号必须与指定的 %s 相对应, %s按顺序会用对应的 : tableName、 displayNameColumnName、 profileUrlColumnName、 imageUrlColumnName、 accessTokenColumnName、 tokenIdColumnName、 refreshTokenColumnName、 expireTimeColumnName、 userIdColumnName、 providerIdColumnName、 providerUserIdColumnName
    ums.repository.addConnectionSqlStringinsert into %s(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)第三方登录用户数据库用户表添加用户语句。 注意: sql 语句中的 %s 必须写上,问号必须与指定的 %s 相对应, %s按顺序会用对应的 : tableName、 userIdColumnName、 providerIdColumnName、 providerUserIdColumnName、 rankColumnName、 displayNameColumnName、 profileUrlColumnName、 imageUrlColumnName、 accessTokenColumnName、 tokenIdColumnName、 refreshTokenColumnName、 expireTimeColumnName
    ums.repository.addConnectionQueryForRankSqlStringselect coalesce(max(%s) + 1, 1) as %s from %s where %s = ? and %s = ?第三方登录用户数据库用户表查询添加用户时的所需 rank 的值。 注意: sql 语句中的 %s 必须写上,问号必须与指定的 %s 相对应,%s按顺序会用对应的 : rankColumnName、 rankColumnName、 tableName、 userIdColumnName、 providerIdColumnName
    ums.repository.removeConnectionsSqlStringdelete from %s where %s = ? and %s = ?第三方登录用户数据库用户表根据 userId 与 providerId 删除多个用户。 注意: sql 语句中的 %s 必须写上,问号必须与指定的 %s 相对应,%s按顺序会用对应的 : tableName、 userIdColumnName、 providerIdColumnName
    ums.repository.removeConnectionSqlStringdelete from %s where %s = ? and %s = ? and %s = ?第三方登录用户数据库用户表根据 userId、providerId、providerUserId 删除一个用户。 注意: sql 语句中的 %s 必须写上,问号必须与指定的 %s 相对应,%s按顺序会用对应的 : tableName、 userIdColumnName、 providerIdColumnName、 providerUserIdColumnName

    六、参与贡献

    1. Fork 本项目
    2. 新建 Feat_xxx 分支
    3. 提交代码
    4. 新建 Pull Request
    展开全文
  • JustAuth实现GitHub登录

    2022-03-19 22:15:45
    uri-encoding: utf-8 spring: session: store-type: none 引入依赖 me.zhyd.oauth JustAuth 1.16.1 创建Request AuthRequest authRequest = new AuthGithubRequest(AuthConfig.builder() .clientId("Client ID") ....

    GitHub创建第三方应用

    具体步骤查看博客:GitHub创建第三方应用

    copy以下三个信息:Client ID、Client Secret和Authorization callback URL

    application.yml配置

    server:
      port: 80
      servlet:
        context-path: /
      tomcat:
        uri-encoding: utf-8
    
    spring:
      session:
        store-type: none
    

    引入依赖

    <dependency>
    	<groupId>me.zhyd.oauth</groupId>
    	<artifactId>JustAuth</artifactId>
    	<version>1.16.1</version>
    </dependency>
    

    创建Request

    AuthRequest authRequest = new AuthGithubRequest(AuthConfig.builder()
                    .clientId("Client ID")
                    .clientSecret("Client Secret")
                    .redirectUri("应用回调地址")
                    .build());
    

    生成授权地址

    String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
    

    完整代码

    IndexController

    package com.ledao.controller;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author LeDao
     * @company
     * @create 2021-07-28 0:05
     */
    @RestController
    public class IndexController {
    
        @RequestMapping("/")
        public String root() {
            return "<h2 style='text-align: center'><a href='/oauth/login/github'>github登录</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href='/oauth/login/gitee'>gitee登录</a></span>";
        }
    
        @RequestMapping("/home")
        public String home() {
            return "<h1>主页</h1>";
        }
    }
    

    JustAuthController

    Client ID、Client Secret和Authorization callback URL更换为自己的,下面代码中的是错误的

    package com.ledao.controller;
    
    import me.zhyd.oauth.config.AuthConfig;
    import me.zhyd.oauth.model.AuthCallback;
    import me.zhyd.oauth.model.AuthResponse;
    import me.zhyd.oauth.request.AuthGiteeRequest;
    import me.zhyd.oauth.request.AuthGithubRequest;
    import me.zhyd.oauth.request.AuthRequest;
    import me.zhyd.oauth.utils.AuthStateUtils;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * @author LeDao
     * @company
     * @create 2021-07-28 0:12
     */
    @RestController
    @RequestMapping("/oauth")
    public class JustAuthController {
    
        /**
         * 重定向
         *
         * @param type
         * @param response
         * @throws IOException
         */
        @RequestMapping("/login/{type}")
        public void login(@PathVariable String type, HttpServletResponse response) throws IOException {
            //创建request
            AuthRequest authRequest = getAuthRequest(type);
            //重定向到授权链接
            response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));
        }
    
        /**
         * 登录后回调
         *
         * @param type
         * @param callback
         * @return
         */
        @RequestMapping("/callback/{type}")
        public AuthResponse callback(@PathVariable String type, AuthCallback callback) {
            //创建request
            AuthRequest authRequest = getAuthRequest(type);
            //登录(获取用户信息)
            AuthResponse authResponse = authRequest.login(callback);
            return authResponse;
        }
    
        /**
         * 授权平台创建响应的request
         *
         * @param type
         * @return
         */
        private AuthRequest getAuthRequest(String type) {
            AuthRequest authRequest = null;
            switch (type) {
                //github平台
                case "github":
                    authRequest = new AuthGithubRequest(AuthConfig.builder()
                            .clientId("803de7712b9908181")
                            .clientSecret("e863222b3de13fe5ca91224e4651c0316e")
                            .redirectUri("http://localhost:80/oauth/callback/github")
                            .build());
                    break;
                //gitee平台
                case "gitee":
                    authRequest = new AuthGiteeRequest(AuthConfig.builder()
                            .clientId("e7c5c4c0cadb936b728b5d87af2ae1f2958c0a2cb24af4daa6f29a5f7")
                            .clientSecret("823a0fd650add2468a8e31ac684b7c614b1783331c73b32bb29040")
                            .redirectUri("http://localhost:80/oauth/callback/gitee")
                            .build());
                    break;
                default:
                    break;
            }
            return authRequest;
        }
    }
    

    结果

    浏览器地址栏输入:http://localhost

    img

    GitHub登录返回的结果

    img

    Gitee登录返回的结果

    img

    PS.

    代码中包含了Gitee登录

    GitHub完整代码地址:https://github.com/a6678696/JustAuthDemo

    更多第三方登录教程查看:https://justauth.wiki/

    如果需要获取返回的用户信息,callback方法返回的数据类型修改为AuthResponse,完整代码如下:(可直接覆盖上面代码)

    /**
     * 登录后回调
     *
     * @param type
     * @param callback
     * @return
     */
    @RequestMapping("/callback/{type}")
    public AuthResponse<AuthUser> callback(@PathVariable String type, AuthCallback callback) {
    	//创建request
    	AuthRequest authRequest = getAuthRequest(type);
    	//登录(获取用户信息)
    	AuthResponse<AuthUser> authResponse = authRequest.login(callback);
    
    	//打印授权回传代码(2000 表示成功,可以用来判断用户登录是否成功)
    	System.out.println("状态码:" + authResponse.getCode());
    
    	//打印用户的昵称、ID、头像
    	System.out.println("用户的uuid:" + authResponse.getData().getUuid());
    	System.out.println("用户的昵称:" + authResponse.getData().getNickname());
    	System.out.println("用户的头像:" + authResponse.getData().getAvatar());
    
    	//打印用户的Token中的access_token
    	System.out.println("access_token:" + authResponse.getData().getToken().getAccessToken());
    	return authResponse;
    }
    
    展开全文
  • 1. 简介   随着科技时代日渐繁荣,越来越多的应用融入我们的生活。...  本文基于JustAuth实现第三方授权登录,选择JustAuth原因如下: 支持Github、Gitee、微博、钉钉、百度、Coding、腾讯云开发者平台、OSChin...

    1. 简介

      随着科技时代日渐繁荣,越来越多的应用融入我们的生活。不同的应用系统不同的用户密码,造成了极差的用户体验。要是能使用常见的应用账号实现全应用的认证登录,将会更加促进应用产品的推广,为生活增加无限乐趣。
      本文基于JustAuth实现第三方授权登录,选择JustAuth原因如下:

    • 支持Github、Gitee、微博、钉钉、百度、Coding、腾讯云开发者平台、OSChina、支付宝、QQ、微信、淘宝、Google、Facebook、抖音、领英、小米、微软、今日头条、Teambition、StackOverflow、Pinterest、人人、华为、企业微信、酷家乐、Gitlab、美团、饿了么和推特等第三方平台的授权登录;
    • 无需去第三方平台找寻繁杂而庞大的SDK文档,JustAuth提供了及其简单的接入方式;
    • 支持自定义OAuth平台;
    • 支持多种方式的State缓存;
    • 支持自定义Http实现;
    • 自定义 Scope,支持更完善的授权体系;
    • 与SpringBoot完美集成,也可整合Spring Security等安全框架;
    • 官网文档详细、完善,按照文档即可完成需求落地。
      官网:https://justauth.wiki/#/

    2. 初始化数据库

      创建数据库justauth,并初始化表结构:

    DROP TABLE IF EXISTS `justauth`.`t_ja_user`;
    CREATE TABLE  `justauth`.`t_ja_user` (
      `uuid` varchar(64) NOT NULL COMMENT '用户第三方系统的唯一id',
      `username` varchar(100) DEFAULT NULL COMMENT '用户名',
      `nickname` varchar(100) DEFAULT NULL COMMENT '用户昵称',
      `avatar` varchar(255) DEFAULT NULL COMMENT '用户头像',
      `blog` varchar(255) DEFAULT NULL COMMENT '用户网址',
      `company` varchar(50) DEFAULT NULL COMMENT '所在公司',
      `location` varchar(255) DEFAULT NULL COMMENT '位置',
      `email` varchar(50) DEFAULT NULL COMMENT '用户邮箱',
      `gender` varchar(10) DEFAULT NULL COMMENT '性别',
      `remark` varchar(500) DEFAULT NULL COMMENT '用户备注(各平台中的用户个人介绍)',
      `source` varchar(20) DEFAULT NULL COMMENT '用户来源',
      PRIMARY KEY (`uuid`)
    );

    3. 示例代码

      使用SpringBoot插件justauth-spring-boot-starter搭建工程。

    • 创建项目
    • 修改pom.xml
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    	<groupId>com.c3stones</groupId>
    	<artifactId>spring-boot-justauth-demo</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<name>spring-boot-justauth-demo</name>
    	<description>Spring Boot JustAuth Demo</description>
    
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>2.2.8.RELEASE</version>
    		<relativePath />
    	</parent>
    
    	<dependencies>
    		<dependency>
    			<groupId>com.xkcoding.justauth</groupId>
    			<artifactId>justauth-spring-boot-starter</artifactId>
    			<version>1.3.4.beta</version>
    		</dependency>
    		<dependency>
    			<groupId>org.apache.commons</groupId>
    			<artifactId>commons-pool2</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>com.baomidou</groupId>
    			<artifactId>mybatis-plus-boot-starter</artifactId>
    			<version>3.3.1</version>
    		</dependency>
    		<dependency>
    			<groupId>mysql</groupId>
    			<artifactId>mysql-connector-java</artifactId>
    			<scope>runtime</scope>
    		</dependency>
    		<dependency>
    			<groupId>cn.hutool</groupId>
    			<artifactId>hutool-all</artifactId>
    			<version>5.4.1</version>
    		</dependency>
    		<dependency>
    			<groupId>org.projectlombok</groupId>
    			<artifactId>lombok</artifactId>
    			<optional>true</optional>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-data-redis</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-configuration-processor</artifactId>
    			<optional>true</optional>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-test</artifactId>
    			<scope>test</scope>
    		</dependency>
    	</dependencies>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    			</plugin>
    		</plugins>
    	</build>
    
    	<repositories>
    		<!--阿里云私服 -->
    		<repository>
    			<id>aliyun</id>
    			<name>aliyun</name>
    			<url>http://maven.aliyun.com/nexus/content/groups/public</url>
    		</repository>
    		<!--中央仓库 -->
    		<repository>
    			<id>oss snapshot</id>
    			<name>oss snapshot</name>
    			<url>http://oss.sonatype.org/content/repositories/snapshots</url>
    			<releases>
    				<enabled>true</enabled>
    			</releases>
    			<snapshots>
    				<enabled>true</enabled>
    			</snapshots>
    		</repository>
    	</repositories>
    
    </project>
    • 创建响应实体
    import lombok.AllArgsConstructor;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    
    /**
     * 响应实体
     * 
     * @author CL
     *
     */
    @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    public class Response {
    
    	/**
    	 * 响应码
    	 */
    	private int code;
    
    	/**
    	 * 响应消息体
    	 */
    	private String msg;
    
    	/**
    	 * 失败响应
    	 * 
    	 * @param msg 响应消息体
    	 * @return
    	 */
    	public static Response error(String msg) {
    		return new Response(500, msg);
    	}
    
    	/**
    	 * 成功响应
    	 * 
    	 * @param msg 响应消息体
    	 * @return
    	 */
    	public static Response success(String msg) {
    		return new Response(200, msg);
    	}
    	
    }
    • 创建Redis配置类
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.boot.autoconfigure.AutoConfigureAfter;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
    import org.springframework.cache.Cache;
    import org.springframework.cache.annotation.CachingConfigurerSupport;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.cache.interceptor.CacheErrorHandler;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.cache.RedisCacheConfiguration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.RedisSerializationContext;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    
    /**
     * Redis配置类
     * 
     * @author CL
     *
     */
    @Slf4j
    @EnableCaching
    @Configuration
    @AutoConfigureAfter(RedisAutoConfiguration.class)
    public class RedisConfig extends CachingConfigurerSupport {
    
    	/**
    	 * 注入RedisTemplate
    	 * 
    	 * @param redisConnectionFactory Redis连接工厂
    	 * @return
    	 */
    	@Bean(name = "redisTemplate")
    	@ConditionalOnMissingBean(name = "redisTemplate")
    	public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
    		RedisTemplate<Object, Object> template = new RedisTemplate<>();
    		template.setValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
    		template.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
    		template.setKeySerializer(new StringRedisSerializer());
    		template.setHashKeySerializer(new StringRedisSerializer());
    		template.setConnectionFactory(redisConnectionFactory);
    		return template;
    	}
    
    	/**
    	 * 缓存错误处理
    	 */
    	@Bean
    	@Override
    	public CacheErrorHandler errorHandler() {
    		log.info("初始化 -> [{}]", "Redis CacheErrorHandler");
    		return new CacheErrorHandler() {
    			@Override
    			public void handleCacheGetError(RuntimeException e, Cache cache, Object key) {
    				log.error("Redis occur handleCacheGetError:key -> [{}]", key, e);
    			}
    
    			@Override
    			public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) {
    				log.error("Redis occur handleCachePutError:key -> [{}];value -> [{}]", key, value, e);
    			}
    
    			@Override
    			public void handleCacheEvictError(RuntimeException e, Cache cache, Object key) {
    				log.error("Redis occur handleCacheEvictError:key -> [{}]", key, e);
    			}
    
    			@Override
    			public void handleCacheClearError(RuntimeException e, Cache cache) {
    				log.error("Redis occur handleCacheClearError:", e);
    			}
    		};
    	}
    
    	/**
    	 * 注入Redis缓存配置类
    	 * 
    	 * @return
    	 */
    	@Bean(name = { "redisCacheConfiguration" })
    	public RedisCacheConfiguration redisCacheConfiguration() {
    		RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
    		configuration = configuration
    				.serializeKeysWith(
    						RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
    				.serializeValuesWith(RedisSerializationContext.SerializationPair
    						.fromSerializer(new Jackson2JsonRedisSerializer<>(Object.class)));
    		return configuration;
    	}
    
    }
    • 创建Token缓存到Redis工具类
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Objects;
    
    import javax.annotation.PostConstruct;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.core.BoundHashOperations;
    import org.springframework.data.redis.core.RedisTemplate;
    
    import com.alibaba.fastjson.JSONObject;
    
    import me.zhyd.oauth.model.AuthToken;
    
    /**
     * 授权Token缓存Redis
     * 
     * @author CL
     *
     */
    @Configuration
    public class JustAuthTokenCache {
    
    	@SuppressWarnings("rawtypes")
    	@Autowired
    	private RedisTemplate redisTemplate;
    
    	private BoundHashOperations<String, String, AuthToken> valueOperations;
    
    	@SuppressWarnings("unchecked")
    	@PostConstruct
    	public void init() {
    		valueOperations = redisTemplate.boundHashOps("JUSTAUTH::TOKEN");
    	}
    
    	/**
    	 * 保存Token
    	 * 
    	 * @param uuid     用户uuid
    	 * @param authUser 授权用户
    	 * @return
    	 */
    	public AuthToken saveorUpdate(String uuid, AuthToken authToken) {
    		valueOperations.put(uuid, authToken);
    		return authToken;
    	}
    
    	/**
    	 * 根据用户uuid查询Token
    	 * 
    	 * @param uuid 用户uuid
    	 * @return
    	 */
    	public AuthToken getByUuid(String uuid) {
    		Object token = valueOperations.get(uuid);
    		if (null == token) {
    			return null;
    		}
    		return JSONObject.parseObject(JSONObject.toJSONString(token), AuthToken.class);
    	}
    
    	/**
    	 * 查询所有Token
    	 * 
    	 * @return
    	 */
    	public List<AuthToken> listAll() {
    		return new LinkedList<>(Objects.requireNonNull(valueOperations.values()));
    	}
    
    	/**
    	 * 根据用户uuid移除Token
    	 * 
    	 * @param uuid 用户uuid
    	 * @return
    	 */
    	public void remove(String uuid) {
    		valueOperations.delete(uuid);
    	}
    
    }
    • 创建实体类
    import java.io.Serializable;
    
    import com.alibaba.fastjson.JSONObject;
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.annotation.TableField;
    import com.baomidou.mybatisplus.annotation.TableId;
    import com.baomidou.mybatisplus.annotation.TableName;
    
    import lombok.AllArgsConstructor;
    import lombok.NoArgsConstructor;
    import me.zhyd.oauth.model.AuthToken;
    import me.zhyd.oauth.model.AuthUser;
    
    /**
     * 授权用户信息
     * 
     * @author CL
     *
     */
    @NoArgsConstructor
    @AllArgsConstructor
    @TableName(value = "t_ja_user")
    public class JustAuthUser extends AuthUser implements Serializable {
    
    	private static final long serialVersionUID = 1L;
    
    	/**
    	 * 用户第三方系统的唯一id。在调用方集成该组件时,可以用uuid + source唯一确定一个用户
    	 */
    	@TableId(type = IdType.INPUT)
    	private String uuid;
    
    	/**
    	 * 用户授权的token信息
    	 */
    	@TableField(exist = false)
    	private AuthToken token;
    
    	/**
    	 * 第三方平台返回的原始用户信息
    	 */
    	@TableField(exist = false)
    	private JSONObject rawUserInfo;
    
    	/**
    	 * 自定义构造函数
    	 * 
    	 * @param authUser 授权成功后的用户信息,根据授权平台的不同,获取的数据完整性也不同
    	 */
    	public JustAuthUser(AuthUser authUser) {
    		super(authUser.getUuid(), authUser.getUsername(), authUser.getNickname(), authUser.getAvatar(),
    				authUser.getBlog(), authUser.getCompany(), authUser.getLocation(), authUser.getEmail(),
    				authUser.getRemark(), authUser.getGender(), authUser.getSource(), authUser.getToken(),
    				authUser.getRawUserInfo());
    	}
    
    }
    • 创建Mapper
    import org.apache.ibatis.annotations.Mapper;
    
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.c3stones.entity.JustAuthUser;
    
    /**
     * 授权用户Mapper
     * 
     * @author CL
     *
     */
    @Mapper
    public interface JustAuthUserMapper extends BaseMapper<JustAuthUser> {
    
    }
    • 创建Service
    import com.baomidou.mybatisplus.extension.service.IService;
    import com.c3stones.entity.JustAuthUser;
    
    /**
     * 授权用户Service
     * 
     * @author CL
     *
     */
    public interface JustAuthUserService extends IService<JustAuthUser> {
    
    	/**
    	 * 保存或更新授权用户
    	 * 
    	 * @param justAuthUser 授权用户
    	 * @return
    	 */
    	boolean saveOrUpdate(JustAuthUser justAuthUser);
    
    	/**
    	 * 根据用户uuid查询信息
    	 * 
    	 * @param uuid 用户uuid
    	 * @return
    	 */
    	JustAuthUser getByUuid(String uuid);
    
    	/**
    	 * 根据用户uuid移除信息
    	 * 
    	 * @param uuid 用户uuid
    	 * @return
    	 */
    	boolean removeByUuid(String uuid);
    
    }
    • 创建Service实现类
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.c3stones.cache.JustAuthTokenCache;
    import com.c3stones.entity.JustAuthUser;
    import com.c3stones.mapper.JustAuthUserMapper;
    import com.c3stones.service.JustAuthUserService;
    
    /**
     * 授权用户Service实现
     * 
     * @author CL
     *
     */
    @Service
    public class JustAuthUserServiceImpl extends ServiceImpl<JustAuthUserMapper, JustAuthUser>
    		implements JustAuthUserService {
    
    	@Autowired
    	private JustAuthTokenCache justAuthTokenCache;
    
    	/**
    	 * 保存或更新授权用户
    	 * 
    	 * @param justAuthUser 授权用户
    	 * @return
    	 */
    	@Override
    	public boolean saveOrUpdate(JustAuthUser justAuthUser) {
    		justAuthTokenCache.saveorUpdate(justAuthUser.getUuid(), justAuthUser.getToken());
    		return super.saveOrUpdate(justAuthUser);
    	}
    
    	/**
    	 * 根据用户uuid查询信息
    	 * 
    	 * @param uuid 用户uuid
    	 * @return
    	 */
    	@Override
    	public JustAuthUser getByUuid(String uuid) {
    		JustAuthUser justAuthUser = super.getById(uuid);
    		if (justAuthUser != null) {
    			justAuthUser.setToken(justAuthTokenCache.getByUuid(uuid));
    		}
    		return justAuthUser;
    	}
    
    	/**
    	 * 根据用户uuid移除信息
    	 * 
    	 * @param uuid 用户uuid
    	 * @return
    	 */
    	@Override
    	public boolean removeByUuid(String uuid) {
    		justAuthTokenCache.remove(uuid);
    		return super.removeById(uuid);
    	}
    
    }
    • 创建授权Controller
    import java.io.IOException;
    
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.alibaba.fastjson.JSON;
    import com.c3stones.common.Response;
    import com.c3stones.entity.JustAuthUser;
    import com.c3stones.service.JustAuthUserService;
    import com.xkcoding.justauth.AuthRequestFactory;
    
    import lombok.extern.slf4j.Slf4j;
    import me.zhyd.oauth.exception.AuthException;
    import me.zhyd.oauth.model.AuthCallback;
    import me.zhyd.oauth.model.AuthResponse;
    import me.zhyd.oauth.model.AuthToken;
    import me.zhyd.oauth.model.AuthUser;
    import me.zhyd.oauth.request.AuthRequest;
    import me.zhyd.oauth.utils.AuthStateUtils;
    
    /**
     * 授权Controller
     * 
     * @author CL
     *
     */
    @Slf4j
    @RestController
    @RequestMapping("/oauth")
    public class AuthController {
    
    	@Autowired
    	private AuthRequestFactory factory;
    
    	@Autowired
    	private JustAuthUserService justAuthUserService;
    
    	/**
    	 * 登录
    	 * 
    	 * @param type     第三方系统类型,例如:gitee/baidu
    	 * @param response
    	 * @throws IOException
    	 */
    	@GetMapping("/login/{type}")
    	public void login(@PathVariable String type, HttpServletResponse response) throws IOException {
    		AuthRequest authRequest = factory.get(type);
    		response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));
    	}
    
    	/**
    	 * 登录回调
    	 * 
    	 * @param type     第三方系统类型,例如:gitee/baidu
    	 * @param callback
    	 * @return
    	 */
    	@SuppressWarnings("unchecked")
    	@RequestMapping("/{type}/callback")
    	public Response login(@PathVariable String type, AuthCallback callback) {
    		AuthRequest authRequest = factory.get(type);
    		AuthResponse<AuthUser> response = authRequest.login(callback);
    		log.info("【response】= {}", JSON.toJSONString(response));
    
    		if (response.ok()) {
    			justAuthUserService.saveOrUpdate(new JustAuthUser(response.getData()));
    			return Response.success(JSON.toJSONString(response));
    		}
    		return Response.error(response.getMsg());
    	}
    
    	/**
    	 * 收回
    	 * 
    	 * @param type 第三方系统类型,例如:gitee/baidu
    	 * @param uuid 用户uuid
    	 * @return
    	 */
    	@SuppressWarnings("unchecked")
    	@RequestMapping("/revoke/{type}/{uuid}")
    	public Response revoke(@PathVariable String type, @PathVariable String uuid) {
    		AuthRequest authRequest = factory.get(type);
    
    		JustAuthUser justAuthUser = justAuthUserService.getByUuid(uuid);
    		if (null == justAuthUser) {
    			return Response.error("用户不存在");
    		}
    
    		AuthResponse<AuthToken> response = null;
    		try {
    			response = authRequest.revoke(justAuthUser.getToken());
    			if (response.ok()) {
    				justAuthUserService.removeByUuid(justAuthUser.getUuid());
    				return Response.success("用户 [" + justAuthUser.getUsername() + "] 的 授权状态 已收回!");
    			}
    			return Response.error("用户 [" + justAuthUser.getUsername() + "] 的 授权状态 收回失败!" + response.getMsg());
    		} catch (AuthException e) {
    			return Response.error(e.getErrorMsg());
    		}
    	}
    
    	/**
    	 * 刷新
    	 * 
    	 * @param type 第三方系统类型,例如:gitee/baidu
    	 * @param uuid 用户uuid
    	 * @return
    	 */
    	@SuppressWarnings("unchecked")
    	@RequestMapping("/refresh/{type}/{uuid}")
    	@ResponseBody
    	public Response refresh(@PathVariable String type, @PathVariable String uuid) {
    		AuthRequest authRequest = factory.get(type);
    
    		JustAuthUser justAuthUser = justAuthUserService.getByUuid(uuid);
    		if (null == justAuthUser) {
    			return Response.error("用户不存在");
    		}
    
    		AuthResponse<AuthToken> response = null;
    		try {
    			response = authRequest.refresh(justAuthUser.getToken());
    			if (response.ok()) {
    				justAuthUser.setToken(response.getData());
    				justAuthUserService.saveOrUpdate(justAuthUser);
    				return Response.success("用户 [" + justAuthUser.getUsername() + "] 的 access token 已刷新!新的 accessToken: "
    						+ response.getData().getAccessToken());
    			}
    			return Response.error("用户 [" + justAuthUser.getUsername() + "] 的 access token 刷新失败!" + response.getMsg());
    		} catch (AuthException e) {
    			return Response.error(e.getErrorMsg());
    		}
    	}
    
    }
    • 创建启动类
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    /**
     * 启动类
     * 
     * @author CL
     *
     */
    @SpringBootApplication
    public class JustAuthApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(JustAuthApplication.class, args);
    	}
    
    }
    • 创建配置文件
        在resources目录下创建application.yml,其中client-idclient-secret待在对应的开放平台创建应用后回填。
    server:
      port: 8443
      
    spring:
      datasource:
          driverClassName: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://127.0.0.1:3306/justauth?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
          username: root
          password: 123456
      redis:
        host: 127.0.0.1
        port: 6379
        password: 123456
        # 连接超时时间(记得添加单位,Duration)
        timeout: 2000ms
        # Redis默认情况下有16个分片,这里配置具体使用的分片
        database: 0
        lettuce:
          pool:
            # 连接池最大连接数(使用负值表示没有限制) 默认 8
            maxActive: 8
            # 连接池中的最大空闲连接 默认 8
            maxIdle: 8
    
    # Mybatis-plus配置
    mybatis-plus:
       mapper-locations: classpath:mapper/*.xml
       global-config:
          db-config:
             id-type: AUTO
       configuration:
          # 打印sql
          log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    
    # 日志配置          
    logging:
      level:
        com.xkcoding: debug
        
    # 第三方系统认证
    justauth:
      enabled: true
      type:
        BAIDU:
          client-id: xxxxxx
          client-secret: xxxxxx
          redirect-uri: http://127.0.0.1:8443/oauth/baidu/callback
        GITEE:
          client-id: xxx
          client-secret: xxx
          redirect-uri: http://127.0.0.1:8443/oauth/gitee/callback
      cache:
        # 缓存类型(default-使用JustAuth内置的缓存、redis-使用Redis缓存、custom-自定义缓存)
        type: redis
        # 缓存前缀,目前只对redis缓存生效,默认 JUSTAUTH::STATE::
        prefix: 'JUATAUTH::STATE::'
        # 超时时长,目前只对redis缓存生效,默认3分钟
        timeout: 3m

    4. 创建应用

    • 百度创建应用
    1. 注册百度开发者账号。
      1.1 注册开发者账号:百度Passport
    2. 创建第三方授权应用
      2.1 配置应用:开发者服务管理
      2.2 创建工程

      2.3 安全设置

        将配置文件中justauth.type.BAIDU.redirect-uri的值http://127.0.0.1:8443/oauth/baidu/callback复制到授权回调页文本框中。
      2.4 信息回填
        将API KeySecret Key复制到配置文件中的justauth.type.BAIDU.client-idjustauth.type.BAIDU.client-secret属性。
      其他第三方平台创建请浏览:集成第三方

    5. 测试

    • 登录
        浏览器访问地址:http://127.0.0.1:8443/oauth/login/baidu,即可获取到对应信息。
        请观察数据库及Redis中数据变化。
    • 刷新Token
        浏览器访问地址:http://127.0.0.1:8443/oauth/refresh/baidu/[uuid],其中uuid为数据库表中的uuid。
        目前插件中已实现的可刷新的第三方应用有限,请查看AuthRequest.refresh方法的实现类。
        请观察Redis中数据变化。
    • 移除Token
        浏览器访问地址:http://127.0.0.1:8443/oauth/revoke/baidu/[uuid],其中uuid为数据库表中的uuid。
        目前插件中已实现的可刷新的第三方应用有限,请查看AuthRequest.revoke方法的实现类。
        请观察数据库及Redis中数据变化。

    6. 项目地址

      spring-boot-justauth-demo

    展开全文
  •   目前很多平台都提供了单点登录授权服务器功能,比如我们经常用到的QQ登录、微信登录、新浪微博登录、...JustAuth是第三方授权登录的工具类库,对接了国外内数十家第三方登录的SDK,我们在需要实现第三方登录时...
  • JustAuth.version>1.13.2</JustAuth.version> <justauth.version>1.3.2</justauth.version> </properties> <dependency> <groupId>me.zhyd.oauth</groupId>
  • JustAuth 是一个开箱即用的整合第三方登录的开源组件,网上没有搜到它在前后端分离系统中的使用案例,本篇文章将以 QQ 登录为例为大家讲解该场景下的使用步骤,建议收藏”01—申请 QQ 应用登录 QQ 互联平台...
  • JustAuth 用户故事:群主,你的代码出 BUG 了! 以下内容改编整理自 JustAuth 社区群,为保护隐私,已经隐去相关关键信息,文章部分内容为润色后的。 场景 小帅哥 在使用 JustAuth 时遇到了一些问题,通过在...
  • 二、 基于SpringBoot整合JustAuth 三部曲 1、pom.xml中引入相关依赖 <!-- reids --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-...
  • JustAuth发布1.10.0版本,集成华为和企业微信登录,更加灵活的state缓存 更新内容 新增 增加AuthCache配置类AuthCacheConfig.java,可以自定义缓存有效期以及是否开启定时任务 简单封装极简版的针对JustAuth的Log...
  • 机缘 ... 链接:百度开放平台 记下api key 和secret key 还有要...没错,我还有杀手锏,就是justauth项目:项目地址 简单介绍下,该项目集成了几十种第三方登陆,傻瓜操作,让新手也可以完全胜任,我的是ssm项目,下面
  • 通过使用JustAuth我们可以快速的集成我们第三方的一些扫码登录功能,其本质是对于各种第三方扫码功能的封装,我们也可以按照自己的需求自行封装,原则上都是调用第三方认证中心的授权接口,完成授权功能,获取到第三...
  • OAuth2 JustAuth实战

    千次阅读 2020-09-03 11:08:28
    1.创建第三方平台应用,申请配置信息 基本上按照这篇博客的...2.加入JustAuth工具类 2.1创建spring boot项目,加入pring-boot-starter-web和lombok依赖 2.2加入JustAuth依赖 // ... <dependency> <groupId&
  • justauth-spring-boot-starter V1.3.5 发布成功 关于 justauth-spring-boot-starter justauth-spring-boot-starter 是 Spring Boot 集成 JustAuth 的最佳实践。如果你的项目是基于 Spring Boot 构建,则推荐你用...
  • v1.15.7-x 版本主要解决的问题是增加自定义 scope 的... 使用了自定义 scope 后的授权流程 其他平台的授权页面 微软: Pinterest: 参考资料 OAuth Scopes JustAuth 集成的平台中,允许自定义 scope 的平台文档 Baidu: ...
  • JustAuth脚手架目前已经对接了大多数常用的平台,包括微信、QQ、企业微信、钉钉、飞书、支付宝等。并且注释都是中文,非常便于阅读。本文章以飞书和企业微信为例做一个测试用例。 pom依赖引入 <dependency> &...
  • 、 https://gitee.com/yadong.zhang/JustAuth) 获取配置信息 想要实现facebook三方登陆,我们需要APPID、APP秘钥、及你跳转成功的回调地址(就是你登录成功之后想让其跳转的地址);开发者地址:...
  • 整合 JustAuth 开源组件实现微信登录。 文档地址:https://justauth.wiki/oauth/wechat_open.html 1、新建一个 Spring Boot 工程 2、引入依赖 <dependency> <groupId>org.springframework.boot</...
  • 什么是 JustAuthJustAuth,如你所见,它仅仅是一个第三方授权登录的工具类库,它可以让我们脱离繁琐的第三方登录 SDK,让登录变得So easy! JustAuth 集成了诸如:Github、Gitee、支付宝、新浪微博、微信、...
  • 前后端分离项目中使用JustAuth第三方登录,Vue+JustAuth+SpringBoot Vue集成JustAuth实现第三方登录
  • spring boot+Vue整合第三方登录JustAuth

    千次阅读 2019-11-21 21:27:13
    JustAuth,如你所见,它仅仅是一个第三方授权登录的工具类库,它可以让我们脱离繁琐的第三方登录SDK,让登录变得So easy! github地址:https://github.com/justauth/JustAuth 对于spirng boot+Vue前后端分离的项目...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 469
精华内容 187
关键字:

JustAuth

友情链接: road-big-city.zip