单点登录——使用Cookie

单点登录——使用Cookie

什么是单点登录?

在一个多系统中,如果用户在一个系统进行了登录操作,则其他系统也自动登录,用户访问其他系统时,不需要再次登录。

典型的例子:淘宝和天猫,一个浏览器中,用户登录了淘宝,再去访问天猫,会发现天猫也是登录状态。

如何实现?

单点登录实现的方法有很多,本文就讲讲最简单实用的——使用Cookie实现单点登录:

闲话少说,项目说话:

本项目中有四个系统,使用springboot搭建,前后端不分离,使用thymeleaf:

  1. login登录系统,端口9000,url:login.codeshop.com
  2. main主系统,端口9010,url:www.codeshop.com
  3. vip系统,端口9011,url:vip.codeshop.com
  4. cart购物车系统,端口9012,url:cart.codeshop.com
从其他系统进入登录系统,参数带上自己的url和端口:
<a th:if="${session.loginUser == null}" href="http://login.codeshop.com:9000/view/login?target=http://vip.codeshop.com:9011/view/index">登录</a>
后端接收到请求,并进行页面跳转:
public String toLogin(@RequestParam(required = false, defaultValue = "") String target,
                          HttpSession session, @CookieValue(required = false, value = "TOKEN") Cookie cookie){
    if(StringUtils.isEmpty(target)){
        // 直接从登录页进来,则默认跳转到首页
        target = "http://www.codeshop.com:9010";
    }
    // 已经登陆的用户再次访问系统登录,就要重定向
    if(cookie != null) {
        String value = cookie.getValue();
        User user = LoginCacheUtil.loginUser.get(value);
        if (user != null) {
            return target;
        }
    }
    // 重定向地址
    session.setAttribute("target", target);
    return "login";
}

注意,这里将跳转过来的url存入了session中,等下登录完成会用到

用户输入用户信息后,后台校验登录信息,并返回原页面:
// 模拟的用户信息
private static List<User> users = new ArrayList<>();
static{
    users.add(new User(0, "yinjw", "yinjw"));
    users.add(new User(1, "yinwei", "yinwei"));
    users.add(new User(2, "Javee", "Javee"));
}

@PostMapping
public String doLogin(User user, HttpSession session, HttpServletResponse response){
    String target = (String) session.getAttribute("target");

    Optional<User> first = users.stream().filter(user1 -> user1.getUserName().equals(user.getUserName()) &&
                                                 user1.getPassword().equals(user.getPassword()))
        .findFirst();
    if(first.isPresent()){
        // 生成随机的token
        String token = UUID.randomUUID().toString();
        Cookie cookie = new Cookie("TOKEN", token);
        cookie.setDomain("codeshop.com");
        response.addCookie(cookie);
        // 将token和用户信息存起来
        LoginCacheUtil.loginUser.put(token, first.get());
    }else{
        session.setAttribute("msg", "用户名或密码错误");
        return "login";
    }

    return "redirect:" + target;
}

User类:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class User {
    private Integer id;
    private String userName;
    private String password;
}

LoginCacheUtil.loginUser是一个Map,用来模拟redis缓存:

public class LoginCacheUtil {
    public static Map<String, User> loginUser = new HashMap<>();
}

用户直接访问某个系统,后端进行cookie校验:
@Autowired
private RestTemplate restTemplate;

@GetMapping("/index")
public String goVip(@CookieValue(required = false, value = "TOKEN") Cookie cookie, HttpSession session){
    if(cookie != null){
        // 获取token
        String token = cookie.getValue();
        if(!StringUtils.isEmpty(token)){
            // 通过token获取登录的用户信息
            Map result = restTemplate.getForObject("http://login.codeshop.com:9000/login/info?token=" + token, Map.class);
            session.setAttribute("loginUser", result);
        }
    }
    return "index";
}
前端通过session中是否存在loginUser来进行控制:
<h1>欢迎来到VIP页面</h1>
<span>
    <a th:if="${session.loginUser == null}" href="http://login.codeshop.com:9000/view/login?target=http://vip.codeshop.com:9011/view/index">登录</a>
    <a th:unless="${session.loginUser == null}" href="http://login.codeshop.com:9000/login/logout?target=http://vip.codeshop.com:9011/view/index">退出</a>
</span>
<p th:unless="${session.loginUser == null}">
    <span style="color: deepskyblue;" th:text="${session.loginUser.userName}"></span> 已登录
</p>

这样,一个简单的单点登录项目就搭建好了

如何获取源码?

所有源码已上传至本人的github仓库,或者直接下载

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值