sso单点登录系统

本文详细介绍了SSO单点登录系统的需求、分析、思路和代码实现。在分布式环境中解决用户多次登录的问题,通过Redis统一管理Session。重点讲述了生成token、将其存入Redis和Cookie,以及使用jsonp跨域查询用户信息的过程。
摘要由CSDN通过智能技术生成

目录

1.需求:

2.分析

3.思路

4.代码实现

用户表DDL

注册服务层

注册表现层

register.jsp

login.jsp

登录服务层

登录表现层

从cookie中取token到redis查询用户信息,js部分(jsonp)

根据token查询用户信息服务层 

根据token查询用户信息表现层


1.需求:

在分布式应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统,登录成功后显示用户信息。

2.分析

传统的登录实现方式,在只有一个web项目时是没有问题的。

                                    

 集群环境下会出现要求用户多次登录的情况。

解决方案:

1.配置tomcat集群。配置tomcatSession复制。节点数不要超过5个。

2.使用单点登录系统,通过redis模拟Session,实现Session的统一管理。

3.思路

  • sso注册功能
  • sso登录功能
  • 用户登录成功后(服务层)使用UUID随机生成一串字符串用来模拟session,命名为token。将token set进Redis,key: "SESSION:"+token value: json字符串形式的user信息,设置session过期时间(半小时),返回token
  • 用户登录成功后(表现层)调用登录服务获取token,将token写入cookie。key: "token" value: token,返回token
  • 用户登录成功后显示用户信息思路
  1. 表现层登录成功后将用户信息传递给页面(每个需要展示用户信息的页面都要写一个controller,不可取)
  2. 前端js查询cookie中的token作为参数,使用ajax向后台发送请求获取用户信息(jsonp跨域——推荐)

4.代码实现

用户表DDL

CREATE TABLE `tb_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL COMMENT '用户名',
  `password` varchar(32) NOT NULL COMMENT '密码,加密存储',
  `phone` varchar(20) DEFAULT NULL COMMENT '注册手机号',
  `email` varchar(50) DEFAULT NULL COMMENT '注册邮箱',
  `created` datetime NOT NULL,
  `updated` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `username` (`username`) USING BTREE,
  UNIQUE KEY `phone` (`phone`) USING BTREE,
  UNIQUE KEY `email` (`email`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='用户表';

注册服务层

package lx.test.sso.service.impl;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import lx.test.mapper.TbUserMapper;
import lx.test.pojo.TbUser;
import lx.test.pojo.TbUserExample;
import lx.test.pojo.TbUserExample.Criteria;
import lx.test.sso.service.RegisterService;
import lx.test.utils.E3Result;
/**
 * 用户注册service
 * @author lx
 *
 */
@Service
public class RegisterServiceImpl implements RegisterService {

	@Autowired
	private TbUserMapper userMapper;
	@Override
	public E3Result checkData(String param, int type) {
		TbUserExample example = new TbUserExample();
		Criteria criteria = example.createCriteria();
		if (type == 1) {
			criteria.andUsernameEqualTo(param);
		} else if (type == 2) {
			criteria.andPhoneEqualTo(param);
		} else if (type == 3) {
			criteria.andEmailEqualTo(param);
		} else {
			return E3Result.build(400, "非法的参数");
		}
		List<TbUser> list = userMapper.selectByExample(example); 
		if(list == null||list.size() == 0){
			return E3Result.ok(true);
		}
		return E3Result.ok(false);
	}
	@Override
	public E3Result register(TbUser user) {
		if (StringUtils.isBlank(user.getUsername())) {
			return E3Result.build(400, "用户名不能为空");
		}
		if (StringUtils.isBlank(user.getPassword())) {
			return E3Result.build(400, "密码不能为空");
		}
		if (StringUtils.isBlank(user.getPhone())) {
			return E3Result.build(400, "手机号不能为空");
		}
		//数据有效性校验1.用户名2.手机号
		E3Result result = checkData(user.getUsername(), 1);
		if(!(boolean) result.getData()){
			return E3Result.build(400, "此用户名已经被使用");
		}
		result = checkData(user.getPhone(), 2);
		if(!(boolean) result.getData()){
			return E3Result.build(400, "此手机号已经被使用");
		}
		user.setCreated(new Date());
		user.setUpdated(new Date());
		String md5pass = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
		user.setPassword(md5pass);
		userMapper.insert(user);
		return E3Result.ok();		
	}

}

注册表现层

package lx.test.sso.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import lx.test.pojo.TbUser;
import lx.test.sso.service.RegisterService;
import lx.test.utils.E3Result;

/**
 * 商品注册controller
 * @author lx
 *
 */
@Controller
public class RegisterController {
	@Autowired
	private RegisterService registerService;

	@RequestMapping("/page/register")
	public String showRegister(){
		return "register";
	}
	@RequestMapping("/user/check/{param}/{type}")
	@ResponseBody
	public E3Result checkData(@PathVariable String param,@PathVariable int type) {
		E3Result result = registerService.checkData(param, type);
		return result;
	}
	@RequestMapping(value="/user/register",method=RequestMethod.POST)
	@ResponseBody
	public E3Result register(TbUser user) {
		E3Result result = registerService.register(user);
		return result;
	}
}

register.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="Cache-Control" content="no-cache,must-revalidate">
    <title>注册-个人用户</title>
    <link rel="stylesheet" type="text/css" href="/css/headerfooter.css" />
<link rel="stylesheet" type="text/css" href="/css/jquery.alerts.css" />
<link rel="stylesheet" type="text/css" href="/css/headerfooterindex.css" />
<script type="text/javascript" src="/js/jquery-1.5.1.min.js"></script>
<script type="text/javascript" src="/js/jquery.cookie.js"></script>
<script type="text/javascript" src="/js/passport.common.js?v20140531"></script>
<script type="text/javascript" src="/js/jquery.alerts.js"></script>
<script type="text/javascript" src="/js/png.js?v20140521"></script>
</head>
<body>
		<!-- header -->
		<div class="header">
			<a href="http://www.e3mall.cn"><img src="/images/logo.png" border="0" /><span>欢迎注册</span></a>
		</div>

		<!--mainStart-->
						<link rel="stylesheet" type="text/css" href="/css/reg.css?v20140432" />
<script type="text/javascript" src="/js/allMail.js?v20140430"></script>
<script type="text/javascript
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值