sso单点登陆实现

Sso系统工程搭建


服务接口实现:

用户登录:

功能分析:

请求的url:/user/login

请求的方法:POST

参数:username、password,表单提交的数据。可以使用方法的形参接收。

返回值:json数据,使用result包含一个token。

登录的业务流程:


登录的处理流程:

1、登录页面提交用户名密码。

2、登录成功后生成token。Token相当于原来的jsessionid,字符串,可以使用uuid。

3、把用户信息保存到redis。Key就是token,value就是TbUser对象转换成json。

4、使用String类型保存Session信息。可以使用“前缀:token”为key

5、设置key的过期时间。模拟Session的过期时间。一般半个小时。

6、把token写入cookie中。

7、Cookie需要跨域。例如www.imooc.com\sso.imooc.com\order.imooc.com,可以使用工具类。jsonp

8、Cookie的有效期。关闭浏览器失效。

9、登录成功。

Dao层:逆向工程
Service:

参数:

1、用户名:String username

2、密码:String password

返回值:result,包装token。

业务逻辑:

1、判断用户名密码是否正确。

2、登录成功后生成token。Token相当于原来的jsessionid,字符串,可以使用uuid。

3、把用户信息保存到redis。Key就是token,value就是TbUser对象转换成json。

4、使用String类型保存Session信息。可以使用“前缀:token”为key

5、设置key的过期时间。模拟Session的过期时间。一般半个小时。

6、返回Result包装token。

        @Override
	public result login(String username, String password) {
		// 1、判断用户名密码是否正确。
		TbUserExample example = new TbUserExample();
		Criteria criteria = example.createCriteria();
		criteria.andUsernameEqualTo(username);
		//查询用户信息
		List<TbUser> list = userMapper.selectByExample(example);
		if (list == null || list.size() == 0) {
			return result.build(400, "用户名或密码错误");
		}
		TbUser user = list.get(0);
		//校验密码
		if (!user.getPassword().equals(DigestUtils.md5DigestAsHex(password.getBytes()))) {
			return result.build(400, "用户名或密码错误");
		}
		// 2、登录成功后生成token。Token相当于原来的jsessionid,字符串,可以使用uuid。
		String token = UUID.randomUUID().toString();
		// 3、把用户信息保存到redis Key就是token,value就是TbUser对象转换成json。
		// 4、使用String类型保存Session信息。可以使用“前缀:token”为key
		user.setPassword(null);
		jedisClient.set(USER_INFO + ":" + token, JsonUtils.objectToJson(user));
		// 5、设置key的过期时间。模拟Session的过期时间。一般半个小时。
		jedisClient.expire(USER_INFO + ":" + token, SESSION_EXPIRE);
		// 6、返回result包装token。
		return result.ok(token);
	}

jedisClient可以参考redis使用方法文章

Controller:

@RequestMapping(value="/user/login", method=RequestMethod.POST)
	@ResponseBody
	public Result login(String username, String password,
			HttpServletRequest request, HttpServletResponse response) {
		// 1、接收两个参数。
		// 2、调用Service进行登录。
		Result result = userService.login(username, password);
		// 3、从返回结果中取token,写入cookie。Cookie要跨域。
		String token = result.getData().toString();
		CookieUtils.setCookie(request, response, COOKIE_TOKEN_KEY, token);
		// 4、响应数据。Json数据。result,其中包含Token。
		return result;
		
	}

通过token查询用户信息

UserService:

@Override
	public Result getUserByToken(String token) {
		// 2、根据token查询redis。
		String json = jedisClient.get(USER_INFO + ":" + token);
		if (StringUtils.isBlank(json)) {
			// 3、如果查询不到数据。返回用户已经过期。
			return Result.build(400, "用户登录已经过期,请重新登录。");
		}
		// 4、如果查询到数据,说明用户已经登录。
		// 5、需要重置key的过期时间。
		jedisClient.expire(USER_INFO + ":" + token, 3600);
		// 6、把json数据转换成TbUser对象,然后使用e3Result包装并返回。
		TbUser user = JsonUtils.jsonToPojo(json, TbUser.class);
		return Result.ok(user);
	}
controller:

	@RequestMapping("/user/token/{token}")
	@ResponseBody
	public Result getUserByToken(@PathVariable String token) {
		Result result = userService.getUserByToken(token);
		return result;
	}

jsonp调用:


用户身份认证:

功能分析

1、使用springmvc的拦截器实现。需要实现一个接口HandlerInterceptor接口。

2、业务逻辑

a)从cookie中取token。

b)没有token,需要跳转到登录页面。

c)有token。调用sso系统的服务,根据token查询用户信息。(使用redis可以实现)

d)如果查不到用户信息。用户登录已经过期。需要跳转到登录页面。

e)查询到用户信息。放行。

拦截器实现:

public class LoginInterceptor implements HandlerInterceptor {
	
	@Value("${TT_TOKEN}")
	private String TT_TOKEN;
	@Value("${SSO_LOGIN_URL}")
	private String SSO_LOGIN_URL;
	
	@Autowired
	private UserService userService;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		//执行Handler之前执行此方法
		// a)从cookie中取token。
		String token = CookieUtils.getCookieValue(request, TT_TOKEN);
		if (StringUtils.isBlank(token)) {
			//取当前请求的url
			String url = request.getRequestURL().toString();
			// b)没有token,需要跳转到登录页面。
			response.sendRedirect(SSO_LOGIN_URL + "?redirectUrl=" + url);
			//拦截
			return false;
		}
		// c)有token。调用sso系统的服务,根据token查询用户信息。
		e3Result result = userService.getUserByToken(token);
		if (result.getStatus() != 200) {
			// d)如果查不到用户信息。用户登录已经过期。需要跳转到登录页面。
			//取当前请求的url
			String url = request.getRequestURL().toString();
			// b)没有token,需要跳转到登录页面。
			response.sendRedirect(SSO_LOGIN_URL + "?redirectUrl=" + url);
			//拦截
			return false;
		}
		// e)查询到用户信息。放行。
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// 执行Handler之后返回ModelAndView之前

	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// 返回ModelAndView之后,执行。异常处理。

	}

}

中springmvc.xml中配置拦截器。

	<!-- 拦截器配置 -->
	<mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/**"/>
			<bean class="cn.imooc.cart.interceptor.LoginInterceptor"/>
		</mvc:interceptor>
	</mvc:interceptors>
实现sso系统的回调

	@RequestMapping("/{page}")
	public String showPage(@PathVariable String page) {
		return page;
	}































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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值