社交登录/创建SpringBoot自定义starter

前言:

根据springBoot自动配置机制可以知道,SpringBoot利用SpringFactories机制,通过SpringFactoriesLoader加载自定义Maven引用工程项目jar包下的META-INF/spring.factories文件,根据文件中所填写的配置类全类名,加载第三方配置类。而这个第三方配置类的作用就是注册所有第三方的Bean,以及加载配置文件信息


第一步:创建配置文件类

配置文件类的作用是读取配置文件中的信息,保存到具体的属性中,方便其他类的使用

那么这个配置信息一般都是在starter被引用的工程中,在application.yaml中对应配置

这也就是在初始化SpringBoot工程的第二步:写配置 (第一步:引Maven)

/**
 * @author: 张旭
 * @date: 2023/2/22 11:11
 * @description: GiteeProperties
 */
@ConfigurationProperties(prefix = "myoauth2login.gitee")
@Data
public class GiteeProperties {
    /**
     * Client ID,在应用主页可以查看到
     */
    private  String openidgitee;
    /**
     * Client Secret
     */
    private  String openkeygitee;
    /**
     * 应用回调地址
     */
    private  String redirectgitee;
}

第二部:创建具体的业务实现类

这里的业务类都不需要加@Component等注解去声明注册Bean,业务类的Bean是在配置类中注册的

  • 创建认证授权的父类,主要定义了一些基本方法,如各种类型的发送http请求
public class Oauth {

    private String clientId;
    private String clientSecret;
    private String redirectUri;

    public Oauth() {}

    /**
     * 获取认证Url
     * @param authorize 路径地址
     * @param params 请求参数
     * @return
     * @throws UnsupportedEncodingException
     */
    protected String getAuthorizeUrl(String authorize, Map<String, String> params) throws UnsupportedEncodingException{
        return HttpKit.initParams(authorize, params);
    }

    protected String doPost(String url, Map<String, String> params) throws IOException, KeyManagementException, NoSuchAlgorithmException, NoSuchProviderException {
        return HttpKit.post(url, params);
    }

    protected String doGet(String url, Map<String, String> params) throws IOException, KeyManagementException, NoSuchAlgorithmException, NoSuchProviderException {
        return HttpKit.get(url, params);
    }

    protected String doGetWithHeaders(String url, Map<String, String> headers) throws IOException, KeyManagementException, NoSuchAlgorithmException, NoSuchProviderException {
        return HttpKit.get(url, null, headers);
    }

    public String getClientId() {
        return clientId;
    }

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }

    public String getClientSecret() {
        return clientSecret;
    }

    public void setClientSecret(String clientSecret) {
        this.clientSecret = clientSecret;
    }

    public String getRedirectUri() {
        return redirectUri;
    }

    public void setRedirectUri(String redirectUri) {
        this.redirectUri = redirectUri;
    }
}
  • 创建具体第三方登录授权业务类
public class Oauth2Gitee extends Oauth {

    private GiteeProperties giteeProperties;

    private static final String AUTH_URL = "https://gitee.com/oauth/authorize";
    private static final String TOKEN_URL = "https://gitee.com/oauth/token";
    private static final String TOKEN_INFO_URL = "https://api.weibo.com/oauth2/get_token_info";
    private static final String USER_INFO_URL = "https://gitee.com/api/v5/user";


    public Oauth2Gitee(GiteeProperties giteeProperties) {
        this.giteeProperties = giteeProperties;
        this.setClientId(giteeProperties.getOpenidgitee());
        this.setClientSecret(giteeProperties.getOpenkeygitee());
        this.setRedirectUri(giteeProperties.getRedirectgitee());
    }


    /**
     * @param @return 设定文件
     * @return String    返回类型
     * @throws UnsupportedEncodingException 获取授权url
     * DOC:https://gitee.com/api/v5/oauth_doc#/
     * @throws
     */
    public String getAuthorizeUrl(String state) throws UnsupportedEncodingException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("response_type", "code");
        params.put("client_id", getClientId());
        params.put("redirect_uri", getRedirectUri());
        if (StringUtils.isNotBlank(state)) {
            //OAuth2.0标准协议建议,利用state参数来防止CSRF攻击。可存储于session或其他cache中
            params.put("state", state);
        }
        return super.getAuthorizeUrl(AUTH_URL, params);
    }


    /**
     * @param @param  code
     * @param @return 设定文件
     * @return String    返回类型
     * @throws NoSuchProviderException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException   获取token
     * @throws
     */
    public String getTokenByCode(String code) throws IOException, KeyManagementException, NoSuchAlgorithmException, NoSuchProviderException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("code", code);
        params.put("client_id", getClientId());
        params.put("client_secret", getClientSecret());
        params.put("grant_type", "authorization_code");
        params.put("redirect_uri", getRedirectUri());
        String token = TokenUtil.getAccessToken(super.doPost(TOKEN_URL, params));
        return token;
    }


    /**
     * @param accessToken
     * @return String    返回类型
     * @throws NoSuchProviderException
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException   获取用户信息
     * DOC:https://gitee.com/api/v5/swagger#/getV5User
     * @throws
     */
    public String getUserInfo(String accessToken) throws IOException, KeyManagementException, NoSuchAlgorithmException, NoSuchProviderException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("access_token", accessToken);
        String userInfo = super.doGet(USER_INFO_URL, params);
        return userInfo;
    }
}
第三步:创建自动配置类
@Configuration
@EnableConfigurationProperties(GiteeProperties.class)
@ConditionalOnProperty(prefix = "myoauth2login" ,value = "gitee" , matchIfMissing = true)
public class Oauth2GiteeAutoConfiguration {
    @Resource
    private GiteeProperties properties;

    @Bean
    @ConditionalOnMissingBean
    public Oauth2Gitee oauth2Gitee(){
        return new Oauth2Gitee(properties);
    }
}
第四步:创建META-INF/spring.factories文件
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.xu.oauth2Login.config.Oauth2GiteeAutoConfiguration

至此,基本的自定义starter内容已经完成,进行Maven打包上传即可被第三方使用

注意事项
  • 由于配置文件类中有业务类需要使用到的信息,所有业务类需要将配置类作为自己的属性来使用其中的信息,因此需要创建有参构造器,在初始化的时候就传入配置类。
public class Oauth2Gitee extends Oauth {
    private GiteeProperties giteeProperties;
    
    public Oauth2Gitee(GiteeProperties giteeProperties) {
        this.giteeProperties = giteeProperties;
        this.setClientId(giteeProperties.getOpenidgitee());
        this.setClientSecret(giteeProperties.getOpenkeygitee());
        this.setRedirectUri(giteeProperties.getRedirectgitee());
    }
}

public class Oauth2GiteeAutoConfiguration {
    @Resource
    private GiteeProperties properties;

    @Bean
    @ConditionalOnMissingBean
    public Oauth2Gitee oauth2Gitee(){
        return new Oauth2Gitee(properties);
    }
}
  • 在配置类中注册业务类Bean的时候,最好是加上一些判断条件,来实现Bean的条件注入,如@ConditionalOnMissingBean
@Bean
@ConditionalOnMissingBean
public Oauth2Gitee oauth2Gitee(){
    return new Oauth2Gitee(properties);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值