【转载】spring-security-oauth2(二十二) 重构注册逻辑

浏览器注册模式

前面的我们社交登录都是基于用户的社交信息都已经存在于数据库中了, 如果用户首次登录该怎么办呢?回顾下我们的浏览器注册逻辑。

具体详细步骤  社交注册

1.当第一次用社交用户信息登录,会默认跳到我们自定义的注册界面

2.在跳到注册页之前,会把第三方用户信息放到session中

3.默认提供一个 /social/user 请求可以拿到我们的用户信息展示用户,注册或绑定后会拿到用户的唯一标识, 调用social数据库服务,把关联信息写入数据库中,完成注册 。

4.再次登录,数据库中有用户信息,则登录成功

上面的流程针对app的实现有问题,因为用户信息都是基于session的。下面我们来进行改造

改造思路

1.把从session存储,放到reids中存储,传入设备id

2.其它流程同上面类似

基于redis的社交用户信息保存工具类  AppSignUpUtils


 
 
  1. package com.rui.tiger.auth.app.social;
  2. import com.rui.tiger.auth.app.AppConstants;
  3. import com.rui.tiger.auth.app.exceptions.AppSecretException;
  4. import org.apache.commons.lang.StringUtils;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.data.redis.core.RedisTemplate;
  7. import org.springframework.social.connect.Connection;
  8. import org.springframework.social.connect.ConnectionData;
  9. import org.springframework.social.connect.ConnectionFactoryLocator;
  10. import org.springframework.social.connect.UsersConnectionRepository;
  11. import org.springframework.stereotype.Component;
  12. import org.springframework.web.context.request.ServletWebRequest;
  13. import org.springframework.web.context.request.WebRequest;
  14. /**
  15. * 社交用户和系统用户的关系注册
  16. * ProviderSignInUtils 模拟其中部分的功能
  17. * @author CaiRui
  18. * @date 2019-04-30 08:28
  19. */
  20. @Component
  21. public class AppSignUpUtils {
  22. @Autowired
  23. private RedisTemplate<Object, Object> redisTemplate;
  24. @Autowired
  25. private UsersConnectionRepository usersConnectionRepository;
  26. @Autowired
  27. private ConnectionFactoryLocator connectionFactoryLocator;
  28. /**
  29. * 保存社交信息到redis
  30. * @param request
  31. * @param connectionData
  32. */
  33. public void saveConnectionData(ServletWebRequest request, ConnectionData connectionData) {
  34. redisTemplate.opsForValue().set(buildKey(request), connectionData);
  35. }
  36. /**
  37. * 社交用户信息入库
  38. * @param request
  39. * @param userId
  40. */
  41. public void doPostSignUp( String userId,WebRequest request) {
  42. String key = buildKey(request);
  43. if(!redisTemplate.hasKey(key)){
  44. throw new AppSecretException( "无法找到缓存的用户社交账号信息");
  45. }
  46. ConnectionData connectionData = (ConnectionData) redisTemplate.opsForValue().get(key);
  47. Connection<?> connection = connectionFactoryLocator.getConnectionFactory(connectionData.getProviderId())
  48. .createConnection(connectionData);
  49. usersConnectionRepository.createConnectionRepository(userId).addConnection(connection);
  50. redisTemplate.delete(key);
  51. }
  52. private String buildKey(WebRequest request) {
  53. String deviceId = request.getHeader(AppConstants.DEFAULT_HEADER_DEVICE_ID);
  54. if (StringUtils.isBlank(deviceId)) {
  55. throw new AppSecretException( "设备id参数不能为空");
  56. }
  57. return "tiger:security:social.connect." + deviceId;
  58. }
  59. }

然后创建SpringSocialConfigurerPostProcessor ,bean生命周期初始化后置处理

 


 
 
  1. package com.rui.tiger.auth.app;
  2. import com.rui.tiger.auth.core.social.TigerSpringSocialConfigurer;
  3. import org.apache.commons.lang.StringUtils;
  4. import org.springframework.beans.BeansException;
  5. import org.springframework.beans.factory.config.BeanPostProcessor;
  6. import org.springframework.stereotype.Component;
  7. /**
  8. * 后置处理器 springbean 初始化之前和之后
  9. *
  10. * @author CaiRui
  11. * @date 2019-04-30 08:42 BeanPostProcessor
  12. */
  13. @Component
  14. public class SpringSocialConfigurerPostProcessor implements BeanPostProcessor {
  15. @Override
  16. public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  17. return bean;
  18. }
  19. @Override
  20. public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  21. if (StringUtils.equals(beanName, "tigerSpringSocialConfigurer")) {
  22. TigerSpringSocialConfigurer configurer = (TigerSpringSocialConfigurer)bean;
  23. configurer.signupUrl( "/social/signUp"); //更换浏览器的默认注册
  24. return configurer;
  25. }
  26. return bean;
  27. }
  28. }

springbean生命周期关系如下:

注册控制器  AppSecurityController


 
 
  1. package com.rui.tiger.auth.app.controller;
  2. import com.rui.tiger.auth.app.social.AppSignUpUtils;
  3. import com.rui.tiger.auth.core.social.SocialUserInfo;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.http.HttpStatus;
  6. import org.springframework.social.connect.Connection;
  7. import org.springframework.social.connect.ConnectionData;
  8. import org.springframework.social.connect.web.ProviderSignInUtils;
  9. import org.springframework.web.bind.annotation.GetMapping;
  10. import org.springframework.web.bind.annotation.ResponseStatus;
  11. import org.springframework.web.bind.annotation.RestController;
  12. import org.springframework.web.context.request.ServletWebRequest;
  13. import javax.servlet.http.HttpServletRequest;
  14. /**
  15. * @author CaiRui
  16. * @date 2019-04-30 08:45
  17. */
  18. @RestController
  19. public class AppSecurityController {
  20. @Autowired
  21. private ProviderSignInUtils providerSignInUtils;
  22. @Autowired
  23. private AppSignUpUtils appSignUpUtils;
  24. @GetMapping( "/social/signUp")
  25. @ResponseStatus(HttpStatus.UNAUTHORIZED)
  26. public SocialUserInfo getSocialUserInfo(HttpServletRequest request) {
  27. SocialUserInfo userInfo = new SocialUserInfo();
  28. Connection<?> connection = providerSignInUtils.getConnectionFromSession( new ServletWebRequest(request));
  29. ConnectionData connectionData=connection.createData();
  30. userInfo.setProviderId(connection.getKey().getProviderId());
  31. userInfo.setProviderUserId(connection.getKey().getProviderUserId());
  32. userInfo.setNickName(connection.getDisplayName());
  33. userInfo.setHeadImg(connection.getImageUrl());
  34. appSignUpUtils.saveConnectionData( new ServletWebRequest(request), connectionData);
  35. return userInfo;
  36. }
  37. }

用户注册的地方也要改成我们的工具类来保存 com.rui.tiger.auth.demo.controller.UserController#regist


 
 
  1. /**
  2. * 社交注册
  3. */
  4. @PostMapping( "/regist")
  5. public void regist(UserVo user, HttpServletRequest request){
  6. // 不管是注册用户还是绑定用户,都会拿到一个用户唯一标识
  7. String username=user.getUsername();
  8. //这里处理绑定或注册用户逻辑
  9. //进行系统用户和社交用户入库动作
  10. appSignUpUtils.doPostSignUp(username, new ServletWebRequest(request));
  11. //providerSignInUtils.doPostSignUp(username, new ServletWebRequest(request));
  12. }

ok 代码完成我们来测试下,测试前记得关闭我们的自动注册社交用户的服务

拿授权码的逻辑通前面类似,断点调试,在浏览器和app之间切换。

1.现将我们库中已有的社交信息修改,就是不存在

2.浏览器环境模拟拿到请求授权地址和授权码

https://graph.qq.com/oauth2.0/show?which=Login&display=pc&client_id=101316278&response_type=code&redirect_uri=http%3A%2F%2Fmrcode.cn%2Fauth%2Fqq&state=637d8b89-28ad-4bac-a510-ad1ef710e7cc

授权码:8C54B950B35140EAA55AF6D9D6FF2F3E  

3. 切换到APP环境 postman发送请求,

 我们看下redis中是否有社交信息,可以看到redis工具类已经生效

 4.用户信息已经达到 我们来注册 

ok社交信息入库成功

 ok 注册逻辑重构完成,下章我们来完成令牌配置

文章转载至:https://blog.csdn.net/ahcr1026212/article/details/89667802

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值