介绍
上一章到的是app传了providerId和openId来实现登录,但这种登录一般是事先需要在数据库中存在数。如果用户一开始注册过社交登录,就无法实现。本章节就讲了另外一种方式,app传code过来,实现登录并自动注册,返回token。
实现功能
社交登录方式2,app传code实现登录并自动注册,返回token。
步骤
实现登录过程中接口类以及实现类
/**
* @author lvhaibao
* @description
* @date 2019/1/8 0008 15:15
*/
public interface SocialAuthenticationFilterPostProcessor {
void process(SocialAuthenticationFilter socialAuthenticationFilter);
}
/**
* @author lvhaibao
* @description
* @date 2019/1/8 0008 15:15
*/
@Component
public class SocialAuthenticationFilterPostProcessorImpl implements SocialAuthenticationFilterPostProcessor {
@Autowired
private AuthenticationSuccessHandler myAuthenticationSuccessHandler;
//登录成功之后,调用成功处理器
@Override
public void process(SocialAuthenticationFilter socialAuthenticationFilter) {
socialAuthenticationFilter.setAuthenticationSuccessHandler(myAuthenticationSuccessHandler);
}
}
在自定义处理社交登录中添加filter
/**
* @author lvhaibao
* @description 自定义生成自己的处理的URL
* @date 2019/1/3 0003 10:27
*/
@Data
public class MySpringSocialConfigurer extends SpringSocialConfigurer {
private String filterProcessesUrl;
private SocialAuthenticationFilterPostProcessor socialAuthenticationFilterPostProcessor;
MySpringSocialConfigurer(String filterProcessesUrl) {
this.filterProcessesUrl = filterProcessesUrl;
}
@SuppressWarnings("unchecked")
@Override
protected <T> T postProcess(T object) {
SocialAuthenticationFilter filter = (SocialAuthenticationFilter) super.postProcess(object);
filter.setFilterProcessesUrl(filterProcessesUrl);
//在自定义处理社交登录中添加filter
if(socialAuthenticationFilterPostProcessor != null){
socialAuthenticationFilterPostProcessor.process(filter);
}
return (T) filter;
}
}
生成这个filter的bean
/**
* @author lvhaibao
* @description bean初始化之前和初始化之后都会经过这个
* @date 2018/12/18 0018 11:07
*/
@Component
public class SpringSocialConfigurePostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(StringUtils.equals(beanName, "mySocialSecurityConfig")){
System.out.println("找到mySocialSecurityConfig");
MySpringSocialConfigurer configurer = (MySpringSocialConfigurer)bean;
//app注册页
configurer.signupUrl("/social/signUp");
return configurer;
}
return bean;
}
}
在社交登录中添加登录过程中的处理
**
* @author lvhaibao
* @description 关于社交的的配置
* @date 2019/1/3 0003 10:21
*/
@Configuration
@EnableSocial
@Order(1)
public class SocialConfig extends SocialConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
private SecurityProperties securityProperties;
@Autowired(required = false)
private ConnectionSignUp connectionSignUp;
@Autowired(required = false)
private SocialAuthenticationFilterPostProcessor socialAuthenticationFilterPostProcessor;
/**
* 创建UsersConnectionRepository
*
* @param connectionFactoryLocator connectionFactoryLocator
* @return repository
*/
@Override
public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
JdbcUsersConnectionRepository repository = new JdbcUsersConnectionRepository(dataSource,
connectionFactoryLocator, Encryptors.noOpText());
//如果不为空
if (connectionSignUp != null) {
repository.setConnectionSignUp(connectionSignUp);
}
return repository;
}
/**
* 生成自己的mySocialSecurityConfig的bean
*
* @return configurer
*/
@Bean
public SpringSocialConfigurer mySocialSecurityConfig() {
String filterProcessesUrl = securityProperties.getSocial().getFilterProcessesUrl();
//配置处理的url
MySpringSocialConfigurer configurer = new MySpringSocialConfigurer(filterProcessesUrl);
//配置注册页
configurer.signupUrl("/defaultSignUp.html");
//处理
configurer.setSocialAuthenticationFilterPostProcessor(socialAuthenticationFilterPostProcessor);
return configurer;
}
@Bean
public ProviderSignInUtils providerSignInUtils(ConnectionFactoryLocator connectionFactoryLocator) {
return new ProviderSignInUtils(connectionFactoryLocator,
getUsersConnectionRepository(connectionFactoryLocator)) {
};
}
}
测试
为了模拟app登录,首先需要获取code。首先需要在OAuth2AuthenticationService这个类中打断点。如图所示:
然后用debug运行项目。在登录页面中点击微信登录,然后关闭项目,页面中就出现如下请求:
继续重启项目,这次不需要debug调试。然后使用post请求如下请求:
项目源码
https://gitee.com/lvhaibao/spring-lhbauth/tree/f15183a593f64d6a9494f1800f9b8ce4498111ae/