当前位置:网站首页>登录认证服务
登录认证服务
2022-06-26 13:26:00 【捕風捉影】
整合短信的普通登录模式:
@PostMapping(value = "/register")
public String register(@Valid UserRegisterVo vos, BindingResult result,
RedirectAttributes attributes) {
//如果有错误回到注册页面
if (result.hasErrors()) {
Map<String, String> errors = result.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
attributes.addFlashAttribute("errors",errors);
//效验出错回到注册页面
return "redirect:http://auth.gulimall.com/reg.html";
}
//1、效验验证码
String code = vos.getCode();
//获取存入Redis里的验证码
String redisCode = stringRedisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + vos.getPhone());
if (!StringUtils.isEmpty(redisCode)) {
//截取字符串
if (code.equals(redisCode.split("_")[0])) {
//删除验证码;令牌机制
stringRedisTemplate.delete(AuthServerConstant.SMS_CODE_CACHE_PREFIX+vos.getPhone());
//验证码通过,真正注册,调用远程服务进行注册 todo 远程调用
R register = memberFeignService.register(vos);
if (register.getCode() == 0) {
//成功
return "redirect:http://auth.gulimall.com/login.html";
} else {
//失败
Map<String, String> errors = new HashMap<>();
errors.put("msg", register.getData("msg",new TypeReference<String>(){
}));
attributes.addFlashAttribute("errors",errors);
return "redirect:http://auth.gulimall.com/reg.html";
}
} else {
//效验出错回到注册页面
Map<String, String> errors = new HashMap<>();
errors.put("code","验证码错误");
attributes.addFlashAttribute("errors",errors);
return "redirect:http://auth.gulimall.com/reg.html";
}
} else {
//效验出错回到注册页面
Map<String, String> errors = new HashMap<>();
errors.put("code","验证码错误");
attributes.addFlashAttribute("errors",errors);
return "redirect:http://auth.gulimall.com/reg.html";
}
}
远程调用
@PostMapping(value = "/register")
public R register(@RequestBody MemberUserRegisterVo vo) {
try {
memberService.register(vo);
} catch (PhoneException e) {
return R.error(BizCodeEnum.PHONE_EXIST_EXCEPTION.getCode(),BizCodeEnum.PHONE_EXIST_EXCEPTION.getMessage());
} catch (UsernameException e) {
return R.error(BizCodeEnum.USER_EXIST_EXCEPTION.getCode(),BizCodeEnum.USER_EXIST_EXCEPTION.getMessage());
}
return R.ok();
}
加密之后存入数据库:
@Override
public void register(MemberUserRegisterVo vo) {
MemberEntity memberEntity = new MemberEntity();
//设置默认等级
MemberLevelEntity levelEntity = memberLevelDao.getDefaultLevel();
memberEntity.setLevelId(levelEntity.getId());
//设置其它的默认信息
//检查用户名和手机号是否唯一。感知异常,异常机制
checkPhoneUnique(vo.getPhone());
checkUserNameUnique(vo.getUserName());
memberEntity.setNickname(vo.getUserName());
memberEntity.setUsername(vo.getUserName());
//密码进行MD5加密
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
String encode = bCryptPasswordEncoder.encode(vo.getPassword());
memberEntity.setPassword(encode);
memberEntity.setMobile(vo.getPhone());
memberEntity.setGender(0);
memberEntity.setCreateTime(new Date());
//保存数据
this.baseMapper.insert(memberEntity);
}
社交登录:
点击社交登录,会转发到对应的服务器,返回code,我们通过这个code进行获取access_token
@Slf4j
@Controller
public class OAuth2Controller {
@Autowired
private MemberFeignService memberFeignService;
@GetMapping(value = "/oauth2.0/weibo/success")
public String weibo(@RequestParam("code") String code, HttpSession session) throws Exception {
Map<String, String> map = new HashMap<>();
map.put("client_id","2077705774");
map.put("client_secret","40af02bd1c7e435ba6a6e9cd3bf799fd");
map.put("grant_type","authorization_code");
map.put("redirect_uri","http://auth.gulimall.com/oauth2.0/weibo/success");
map.put("code",code);
//1、根据用户授权返回的code换取access_token 在服务器上做一次post请求
HttpResponse response = HttpUtils.doPost("https://api.weibo.com", "/oauth2/access_token", "post", new HashMap<>(), map, new HashMap<>());
//2、处理
if (response.getStatusLine().getStatusCode() == 200) {
//获取到了access_token,转为通用社交登录对象
String json = EntityUtils.toString(response.getEntity());
//String json = JSON.toJSONString(response.getEntity());
SocialUser socialUser = JSON.parseObject(json, SocialUser.class);
//知道了哪个社交用户
//1)、当前用户如果是第一次进网站,自动注册进来(为当前社交用户生成一个会员信息,以后这个社交账号就对应指定的会员)
//登录或者注册这个社交用户 社交用户有一个特点,注册和登录是写在一起的
System.out.println(socialUser.getAccess_token());
//调用远程服务
R oauthLogin = memberFeignService.oauthLogin(socialUser);
if (oauthLogin.getCode() == 0) {
MemberResponseVo data = oauthLogin.getData("data", new TypeReference<MemberResponseVo>() {
});
log.info("登录成功:用户信息:{}",data.toString());
//1、第一次使用session,命令浏览器保存卡号,JSESSIONID这个cookie
//以后浏览器访问哪个网站就会带上这个网站的cookie
//TODO 1、默认发的令牌。当前域(解决子域session共享问题)
//TODO 2、使用JSON的序列化方式来序列化对象到Redis中
session.setAttribute(LOGIN_USER,data);
//2、登录成功跳回首页
return "redirect:http://gulimall.com";
} else {
return "redirect:http://auth.gulimall.com/login.html";
}
} else {
return "redirect:http://auth.gulimall.com/login.html";
}
}
}
远程调用:
@FeignClient("gulimall-member")
public interface MemberFeignService {
@PostMapping(value = "/member/member/register")
R register(@RequestBody UserRegisterVo vo);
@PostMapping(value = "/member/member/loggin")
R login(@RequestBody UserLoginVo vo);
@PostMapping(value = "/member/member/oauth2/login")
R oauthLogin(@RequestBody SocialUser socialUser) throws Exception;
@PostMapping(value = "/member/member/weixin/login")
R weixinLogin(@RequestParam("accessTokenInfo") String accessTokenInfo);
}
controller:
@PostMapping(value = "/oauth2/login")
public R oauthLogin(@RequestBody SocialUser socialUser) throws Exception {
MemberEntity memberEntity = memberService.login(socialUser);
if (memberEntity != null) {
return R.ok().setData(memberEntity);
} else {
return R.error(BizCodeEnum.LOGINACCT_PASSWORD_EXCEPTION.getCode(),BizCodeEnum.LOGINACCT_PASSWORD_EXCEPTION.getMessage());
}
}
一个方法登录和注册一起实现:
@Override
public MemberEntity login(SocialUser socialUser) throws Exception {
//具有登录和注册逻辑
String uid = socialUser.getUid();
//1、判断当前社交用户是否已经登录过系统
MemberEntity memberEntity = this.baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("social_uid", uid));
if (memberEntity != null) {
//这个用户已经注册过
//更新用户的访问令牌的时间和access_token
MemberEntity update = new MemberEntity();
update.setId(memberEntity.getId());
update.setAccessToken(socialUser.getAccess_token());
update.setExpiresIn(socialUser.getExpires_in());
this.baseMapper.updateById(update);
memberEntity.setAccessToken(socialUser.getAccess_token());
memberEntity.setExpiresIn(socialUser.getExpires_in());
return memberEntity;
} else {
//2、没有查到当前社交用户对应的记录我们就需要注册一个
MemberEntity register = new MemberEntity();
//3、查询当前社交用户的社交账号信息(昵称、性别等)
Map<String,String> query = new HashMap<>();
query.put("access_token",socialUser.getAccess_token());
query.put("uid",socialUser.getUid());
HttpResponse response = HttpUtils.doGet("https://api.weibo.com", "/2/users/show.json", "get", new HashMap<String, String>(), query);
if (response.getStatusLine().getStatusCode() == 200) {
//查询成功
String json = EntityUtils.toString(response.getEntity());
JSONObject jsonObject = JSON.parseObject(json);
String name = jsonObject.getString("name");
String gender = jsonObject.getString("gender");
String profileImageUrl = jsonObject.getString("profile_image_url");
register.setNickname(name);
register.setGender("m".equals(gender)?1:0);
register.setHeader(profileImageUrl);
register.setCreateTime(new Date());
register.setSocialUid(socialUser.getUid());
register.setAccessToken(socialUser.getAccess_token());
register.setExpiresIn(socialUser.getExpires_in());
//把用户信息插入到数据库中
this.baseMapper.insert(register);
}
return register;
}
}
session不同步问题:
使用springsession进行管理
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 整合springsession -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
@EnableRedisHttpSession //整合Redis作为session存储 启动类
配置类指定session存储的位置,不是服务器,而是redis中
但是接受的参数都是对象类型,存储redis都是需要的是 json类型:
创建配置类:
@Configuration
public class GulimallSessionConfig {
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
//放大作用域
cookieSerializer.setDomainName("gulimall.com");
cookieSerializer.setCookieName("GULISESSION");
return cookieSerializer;
}
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
}
边栏推荐
- Never use redis expired monitoring to implement scheduled tasks!
- D中不用GC
- 免费的机器学习数据集网站(6300+数据集)
- 虫子 内存管理 上
- Bug memory management
- 永远不要使用Redis过期监听实现定时任务!
- Niuke challenge 53:c. strange magic array
- Half search, character array definition, character array uses D11
- How to check if a text field is empty or not in swift
- [cqoi2015] task query system
猜你喜欢

Wechat applet -picker component is repackaged and the disabled attribute is added -- above

Sword finger offer 21.57.58 I Double pointer (simple)

How to call self written functions in MATLAB

量化框架backtrader之一文读懂observer观测器

windows版MySQL软件的安装与卸载

常用控件及自定义控件

Freefilesync folder comparison and synchronization software

数学建模经验分享:国赛美赛对比/选题参考/常用技巧

Sword finger offer 15.65.56 I 56Ⅱ. Bit operation (simple - medium)

9項規定6個嚴禁!教育部、應急管理部聯合印發《校外培訓機構消防安全管理九項規定》
随机推荐
SwiftUI找回丢失的列表视图(List)动画
Knowledge about adsorption
Gee - Global Human Settlements grid data 1975-1990-2000-2014
PHP非对称加密算法(RSA)加密机制设计
Luogu p4513 xiaobaiguang Park
Sword finger offer 45.61 Sort (simple)
Bug memory management
Win10 home vs pro vs enterprise vs enterprise LTSC
How to convert data in cell cell into data in matrix
In insect classes and objects
Common operation and Principle Exploration of stream
A must for programmers, an artifact utools that can improve your work efficiency n times
虫子 运算符重载的一个好玩的
Generation and rendering of VTK cylinder
Never use redis expired monitoring to implement scheduled tasks!
[cqoi2015] task query system
Formal parameters vs actual parameters
Hands on data analysis unit 3 model building and evaluation
Eigen(3):error: ‘Eigen’ has not been declared
Notes: the 11th and 12th generation mobile versions of Intel support the native thunderbolt4 interface, but the desktop version does not