登录功能 您所在的位置:网站首页 微博登陆后怎么退出 登录功能

登录功能

2024-07-14 17:31| 来源: 网络整理| 查看: 265

08、单点登录与社交登录.pdf

登录功能 一.账户登录介绍1.介绍1.1 功能需求- 数据:用户名(手机)+密码1.2 登录-数据的封装的实体类(auth)1.3 登录(远程member)1.3.1 登录的实体类1.3.2 登录的controller1.3.3 登录的service实现类 1.4 登录(auth)1.4.1 登录的feign的service(auth)1.4.2 登录的controller(auth)1.4.3 登录的页面渲染login.html(auth)1.4.4 登录的测试 ok 二.社交登录介绍1.介绍2.OAuth2.03.微博登陆 准备3.1 进入微博开放平台3.1.1 步骤3.1.2 修改login.html1). 引导用户到授权页2). 用户授权成功,页面跳转至3) . 换取Access Token4). 使用获得的Access Token调用API5). 其他端口6). 注意: 3.2 社交登录回调-代码3.2.1 member项目1).controller2).service实现类MemberServiceImpl 3.2.2 auth项目1).feigin接口--(远程调用member的社交登录)2).MemberRespVo(登录后的响应数据)3).Oauth2Controller4).login.html5).测试,ok 4.session的数据共享-跨域4.1 问题描述。登录成功后在产品首页数据显示问题,如何携带数据进行跨域?4.2 解决方案4.2.1.方案一:session,不合适,session不能在不同域名之间共享1).session共享原理2).session的问题a.session不能跨不同域共享b.同一个服务,复制多份,session不同步问题c.不同服务,session不能共享问题 4.2.2.方案二:分布式session1).问题2).session共享问题解决a. session复制(占内存,不可取)b. 客户端存储(不安全,不可取)c. hash一致性(有缺点,但可用)d.统一存储(可用)--使用springSessione.springSession整合了session统一存储 4.2.3.方案二:Springsession 5.SpringSession1.介绍,子域向父域扩展1.1 需求描述1.2 问题描述,session共享问题,子域session共享 2.应用--auth、product2.1.导入依赖2.2.配置2.3.启动类2.4.配置类2.5.auth的controller使用session2.6.product的index.html使用session数据 3.springSession原理4.springSession其他操作1).product的首页index.html页面修改2).product的首页index.html的退出操作a.退出标签+jsb.退出的方法 3).登录跳转(如果已经登录成功,再次刷新登录页面,直接跳转到首页)4).search的页面关于登录注册的修改a.导入依赖b.配置c.启动类d.配置类e.list.html修改 登录、注册 三.多系统登录-单点登录1.介绍

一.账户登录介绍 1.介绍 1.1 功能需求- 数据:用户名(手机)+密码

在这里插入图片描述

1.2 登录-数据的封装的实体类(auth) @Data public class UserLoginVo { //loginAccount private String loginacct; private String password; } 1.3 登录(远程member) 1.3.1 登录的实体类 @Data public class MemberLoginVo { private String loginacct; private String password; } 1.3.2 登录的controller //登录服务 @PostMapping("/login") public R login(@RequestBody MemberLoginVo vo) { MemberEntity entity= memberService.login(vo); if (entity!=null){ System.out.println("member的远程MemberController登录成功"); return R.ok().put("member",entity); }else { System.out.println("MemberController登录失败"); return R.error(BizCodeEnume.LOGINACCT_PASSWORD_EXCEPTION.getCode(),BizCodeEnume.LOGINACCT_PASSWORD_EXCEPTION.getMsg()); } } 1.3.3 登录的service实现类 //2.登录服务 @Override public MemberEntity login(MemberLoginVo vo) { String loginacct = vo.getLoginacct(); String password = vo.getPassword(); //1.去数据库查询 QueryWrapper wrapper = new QueryWrapper().eq("username", loginacct).or().eq("mobile", loginacct); MemberEntity memberEntity = baseMapper.selectOne(wrapper); if (memberEntity == null) { System.out.println("登录失败!"+"数据库 数据不存在"); return null; } else { //2.判断密码是否正确 BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); boolean matches = passwordEncoder.matches(password, memberEntity.getPassword()); if (matches) { System.out.println("member的实现类,登录成功"); return memberEntity; } else { System.out.println("登录失败!"+"密码错误"); return null; } } } 1.4 登录(auth) 1.4.1 登录的feign的service(auth) @FeignClient("gulimall-member") public interface MemberFeignService { //由于MemberLoginVo 与UserLoginVo 使用相同属性,所以使用auth的UserLoginVo @PostMapping("/member/member/login") //public R login(@RequestBody MemberLoginVo vo) R login(@RequestBody UserLoginVo vo); } 1.4.2 登录的controller(auth) //login 功能 @PostMapping("/login") public String login(UserLoginVo vo,RedirectAttributes redirectAttributes){ System.out.println("vo: "+vo); //远程登录member R r = memberFeignService.login(vo); if (r.getCode()==0){ //成功 System.out.println("auth的LoginController登录成功"); return "redirect:http://gulimall.com"; }else { System.out.println("auth的LoginController登录失败"); Map errors = new HashMap(); errors.put("msg", r.getData("msg",new TypeReference() {})); redirectAttributes.addFlashAttribute("errors", errors); return "redirect:http://auth.gulimall.com/login.html"; } } 1.4.3 登录的页面渲染login.html(auth)

在这里插入图片描述

1.4.4 登录的测试 ok 二.社交登录介绍 1.介绍

在这里插入图片描述

2.OAuth2.0

 OAuth: OAuth(开放授权)是一个开放标准,允许用户授权第三方网站访问他们存储 在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们 数据的所有内容。  OAuth2.0:对于用户相关的OpenAPI(例如获取用户信息,动态同步,照片,日志,分 享等),为了保护用户数据的安全和隐私,第三方网站访问用户数据前都需要显式的向用户征求授权。  官方版流程: 在这里插入图片描述 (A)用户打开客户端以后,客户端要求用户给予授权。 (B)用户同意给予客户端授权。 (C)客户端使用上一步获得的授权,向认证服务器申请令牌。 (D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。 (E)客户端使用令牌,向资源服务器申请获取资源。 (F)资源服务器确认令牌无误,同意向客户端开放资源。 在这里插入图片描述

3.微博登陆 准备 3.1 进入微博开放平台 3.1.1 步骤

在这里插入图片描述

OAuth2.0授权服务,查看文档

3.1.2 修改login.html 1). 引导用户到授权页

https://api.weibo.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI

client_id:设置自己的client_id 在这里插入图片描述redirect_uri:设置自己的redirect_uri 在这里插入图片描述

2). 用户授权成功,页面跳转至

YOUR_REGISTERED_REDIRECT_URI/?code=CODE

3) . 换取Access Token

login.html页面,点击微博登录按钮,先登录 在这里插入图片描述 获取:code 在这里插入图片描述 再 换取Access Token

https://api.weibo.com/oauth2/access_token?client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=authorization_code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI&code=CODE

其中client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET可以使用basic方式加入header中,返回值 在这里插入图片描述Access Token为:

在这里插入图片描述

4). 使用获得的Access Token调用API 5). 其他端口

在这里插入图片描述

6). 注意:

在这里插入图片描述

3.2 社交登录回调-代码 3.2.1 member项目 1).controller //社交登录-登录服务 @PostMapping("/oauth2/login") public R oauthLogin(@RequestBody SocialUser socialUser) throws Exception { MemberEntity memberEntity= memberService.oauthLogin(socialUser); if (memberEntity!=null){ //TODO 1.成功登录处理 return R.ok().setData(memberEntity); }else { return R.error(BizCodeEnume.LOGINACCT_PASSWORD_EXCEPTION.getCode(),BizCodeEnume.LOGINACCT_PASSWORD_EXCEPTION.getMsg()); } } 2).service实现类MemberServiceImpl //3.社交登录-登录服务 @Override public MemberEntity oauthLogin(SocialUser socialUser) throws Exception { //登录和注册合并逻辑 String uid = socialUser.getUid(); //1.判断当前社交用户,是否登录过系统 MemberEntity memberEntity = baseMapper.selectOne(new QueryWrapper().eq("social_uid", uid)); if (memberEntity != null) { //此用户已经注册,更新数据 MemberEntity update = new MemberEntity(); update.setId(memberEntity.getId()); update.setAccessToken(socialUser.getAccess_token()); update.setExpiresIn(socialUser.getExpires_in()); baseMapper.updateById(update); memberEntity.setAccessToken(socialUser.getAccess_token()); memberEntity.setExpiresIn(socialUser.getExpires_in()); return memberEntity; } else { //2.数据库没此数据,注册一个(说明没有登录过) MemberEntity register = new MemberEntity(); //3.查询当前社交用户的社交账号信息(昵称性别等)--查询微博后台数据 try { HashMap 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(), 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"); //省略其他信息.... register.setNickname(name); register.setUsername(name); register.setLevelId(1L); register.setCreateTime(new Date()); register.setGender("m".equals(gender) ? 1 : 0); //省略其他信息.... } } catch (Exception e) { e.printStackTrace(); } register.setSocialUid(socialUser.getUid()); register.setAccessToken(socialUser.getAccess_token()); register.setExpiresIn(socialUser.getExpires_in()); System.out.println("register: "+register); baseMapper.insert(register); return register; } } 3.2.2 auth项目 1).feigin接口–(远程调用member的社交登录) @FeignClient("gulimall-member") public interface MemberFeignService { //社交登录-登录服务(微博) @PostMapping("/member/member/oauth2/login") public R oauthLogin(@RequestBody SocialUser socialUser) throws Exception; } 2).MemberRespVo(登录后的响应数据) @Data @ToString public class MemberRespVo implements Serializable { private Long id; /**会员等级id*/ private Long levelId; /** 用户名*/ private String username; /*** 密码 */ private String password; /** * 昵称*/ private String nickname; /*** 手机号码 */ private String mobile; /** * 邮箱 */ private String email; /** * 头像 */ private String header; /** * 性别 */ private Integer gender; /** * 生日 */ private Date birth; /** * 所在城市 */ private String city; /** * 职业 */ private String job; /** * 个性签名 */ private String sign; /** * 用户来源 */ private Integer sourceType; /** * 积分 */ private Integer integration; /** * 成长值 */ private Integer growth; /** * 启用状态 */ private Integer status; /** * 注册时间 */ private Date createTime; /** 社交登录UID */ private String socialUid; /** 社交登录TOKEN */ private String accessToken; /** 社交登录过期时间 */ private Long expiresIn; } 3).Oauth2Controller @Autowired private MemberFeignService memberFeignService; //社交登录 @GetMapping("/oauth2.0/weibo/success") public String weibo(@RequestParam("code") String code, HttpSession session) throws Exception { Map map = new HashMap(); map.put("client_id","3133671081"); map.put("client_secret","99b103a33786d6af71338bc796bc242f"); map.put("grant_type","authorization_code"); map.put("redirect_uri","http://auth.gulimall.com/oauth2.0/weibo/success"); map.put("code",code); System.out.println("code: "+code); //1、根据用户授权返回的code换取access_token HttpResponse response = HttpUtils.doPost("https://api.weibo.com", "/oauth2/access_token", "post", new HashMap(), map, new HashMap()); //2、处理 System.out.println("response.getStatusLine().getStatusCode(): "+response.getStatusLine().getStatusCode()); 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) { MemberRespVo data = oauthLogin.getData("data", new TypeReference() {}); log.info("登录成功:用户信息:{}",data.toString()); //2、登录成功跳回首页 return "redirect:http://gulimall.com"; } else { System.out.println("登录失败1"); return "redirect:http://auth.gulimall.com/login.html"; } } else { System.out.println("登录失败"); return "redirect:http://auth.gulimall.com/login.html"; } } 4).login.html 5).测试,ok

点击登录,跳转登录页面,点击微博,授权后,登录成功,返回商品首页(gulimall.com)

4.session的数据共享-跨域 4.1 问题描述。登录成功后在产品首页数据显示问题,如何携带数据进行跨域?

当社交登录微博成功之后,会跳转到产品首页(gulimall.com),(auth项目—>product项目)。那么如何携带数据,首页显示登录后的数据呢?

4.2 解决方案 4.2.1.方案一:session,不合适,session不能在不同域名之间共享

由于微博登录后,从auth项目,跳转到product项目,跨了域名。因为session不能跨域名共享,所以session不可用。

1).session共享原理

在这里插入图片描述 在这里插入图片描述

2).session的问题 a.session不能跨不同域共享 b.同一个服务,复制多份,session不同步问题 c.不同服务,session不能共享问题 4.2.2.方案二:分布式session 1).问题

在这里插入图片描述

2).session共享问题解决 a. session复制(占内存,不可取)

session传输需要时间,占内存 在这里插入图片描述

b. 客户端存储(不安全,不可取)

不安全,cookie长度有限制,不能保存大量信息 在这里插入图片描述

c. hash一致性(有缺点,但可用)

缺点:web_server不能 在这里插入图片描述

d.统一存储(可用)–使用springSession

缺点:修改大量代码 优点:不担心服务器的水平扩展,服务器宕机问题 在这里插入图片描述

e.springSession整合了session统一存储 4.2.3.方案二:Springsession 5.SpringSession

SpringSession文档 HttpSession with Redis文档

1.介绍,子域向父域扩展 1.1 需求描述

auth的微博登录后,跳转到product的首页。auth.gulimall.com—>gulimall.com

1.2 问题描述,session共享问题,子域session共享

在这里插入图片描述

2.应用–auth、product 2.1.导入依赖 org.springframework.session spring-session-data-redis org.springframework.boot spring-boot-starter-data-redis 2.2.配置 #配置redis spring.redis.host=192.168.56.10 spring.redis.port=6379 #session保存到redis spring.session.store-type=redis #设置session过期时间 server.servlet.session.timeout=30m 2.3.启动类 @EnableRedisHttpSession //整合Redis作为session存储 2.4.配置类 @Configuration public class SessionConfig { @Bean public CookieSerializer cookieSerializer() { DefaultCookieSerializer serializer = new DefaultCookieSerializer(); serializer.setCookieName("GULISESSION"); // serializer.setCookiePath("/"); serializer.setDomainName("gulimall.com"); return serializer; } @Bean public RedisSerializer springSessionDefaultRedisSerializer(){ return new GenericJackson2JsonRedisSerializer(); } } 2.5.auth的controller使用session public String weibo(@RequestParam("code") String code, HttpSession session){ session.setAttribute("LOGIN_USER",data); } 2.6.product的index.html使用session数据 你好,请登录: [[${session.LOGIN_USER==null?'':session.LOGIN_USER.nickname}]] 3.springSession原理

在这里插入图片描述

4.springSession其他操作 1).product的首页index.html页面修改 欢迎您,[[${session.loginUser==null?'':session.loginUser.nickname}]] 退出 请您登录! 免费注册 2).product的首页index.html的退出操作 a.退出标签+js 退出 //登录退出,清除session $(".loginOut").click(function () { var result = confirm("确定要退出吗?"); if(result){ location.href="http://auth.gulimall.com/logout"; } }) b.退出的方法 //login退出 功能 @RequestMapping("logout") public String tologout(HttpServletRequest request){ /* 清除session的方案一 */ Enumeration em = request.getSession().getAttributeNames(); while(em.hasMoreElements()){ request.getSession().removeAttribute(em.nextElement().toString()); request.getSession().removeAttribute(AuthServerConstant.LOGIN_USER); } /* 清除session的方案二 */ // HttpSession session = request.getSession(); // session.invalidate(); return "redirect:http://gulimall.com"; } 3).登录跳转(如果已经登录成功,再次刷新登录页面,直接跳转到首页) //登录页 @GetMapping("/login.html") public String loginPage(HttpSession session){ Object attribute = session.getAttribute(AuthServerConstant.LOGIN_USER); if (attribute==null){ //未登录。返回登录页 return "login"; }else { //登录成功,重定向到商品首页 return "redirect:http://gulimall.com"; } } 4).search的页面关于登录注册的修改 a.导入依赖 org.springframework.session spring-session-data-redis org.springframework.boot spring-boot-starter-data-redis b.配置 #配置redis spring.redis.host=192.168.56.10 spring.redis.port=6379 #session保存到redis spring.session.store-type=redis #设置session过期时间 server.servlet.session.timeout=30m c.启动类 @EnableRedisHttpSession //整合Redis作为session存储 d.配置类 @Configuration public class SessionConfig { @Bean public CookieSerializer cookieSerializer() { DefaultCookieSerializer serializer = new DefaultCookieSerializer(); serializer.setCookieName("GULISESSION"); // serializer.setCookiePath("/"); serializer.setDomainName("gulimall.com"); return serializer; } @Bean public RedisSerializer springSessionDefaultRedisSerializer(){ return new GenericJackson2JsonRedisSerializer(); } } e.list.html修改 登录、注册 欢迎您,[[${session.loginUser==null?'':session.loginUser.nickname}]] 主人,请登录 免费注册 三.多系统登录-单点登录 1.介绍

在谷粒商城项目呢,实现了微博、账号登录,仅仅是单系统登录,多系统登录怎么办呢? 多系统登录,实现一个登录,多系统使用。

在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有