package com.tttttt.portal.controller;

import java.util.HashMap;
import java.util.Map; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody; import com.tttttt.manager.pojo.User;
import com.tttttt.portal.util.CookieUtils;
import com.tttttt.sso.service.UserService; @Controller
@RequestMapping("user")
public class UserController { @Autowired
private UserService userService; @Value("${TT_TICKET}")
private String TT_TICKET; // type : "POST",
// //url : "/service/user/doRegister",
// url : "/user/doRegister.html",
// data : {password:_password,username:_username,phone:_phone},
// dataType : 'json',
// if(result.status == "200")
/**
* 用户注册
*
* @param user
* @return
*/
@RequestMapping(value = "doRegister", method = RequestMethod.POST)
@ResponseBody
public Map<String, Object> doRegister(User user) {
// 调用sso服务注册用户
this.userService.saveUser(user); // 封装返回数据map
Map<String, Object> map = new HashMap<>();
map.put("status", "200"); return map;
} // type: "POST",
// url: "/service/user/doLogin?r=" + Math.random(),
// data: {username:_username,password:_password},
// dataType : "json",
// if (obj.status == 200)
/**
* 用户登录
*
* @param request
* @param response
* @param user
* @return
*/
@RequestMapping(value = "doLogin", method = RequestMethod.POST)
@ResponseBody
public Map<String, Object> doLogin(HttpServletRequest request, HttpServletResponse response, User user) {
// 声明返回的map
Map<String, Object> map = new HashMap<>(); // 调用单点登录服务,执行用户登录操作,返回ticket
String ticket = this.userService.doLogin(user); // 判断ticket是否为非空
if (StringUtils.isNotBlank(ticket)) {
// 如果为非空表示登录成功
// 把ticket放到cookie中
CookieUtils.setCookie(request, response, this.TT_TICKET, ticket, 60 * 60 * 24, true); // 封装返回数据
map.put("status", 200);
} // 如果为空,表示登录失败,什么都不做 // 返回结果
return map; } }
package com.tttttt.sso.service;

import com.tttttt.manager.pojo.User;

public interface UserService {

    /**
* 检查数据是否可用
*
* @param param
* @param type
* @return
*/
Boolean check(String param, Integer type); /**
* 根据Ticket查询用户
*
* @param ticket
* @return
*/
User queryUserByTicket(String ticket); /**
* 用户注册
*
* @param user
*/
void saveUser(User user); /**
* 用户登录
*
* @param user
* @return
*/
String doLogin(User user); }
package com.tttttt.sso.service.impl;

import java.io.IOException;
import java.util.Date; import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tttttt.manager.mapper.UserMapper;
import com.tttttt.manager.pojo.User;
import com.tttttt.sso.redis.RedisUtils;
import com.tttttt.sso.service.UserService; @Service
public class UserServiceImpl implements UserService { private static final ObjectMapper MAPPER = new ObjectMapper(); @Autowired
private UserMapper userMapper; @Value("${tttttt_TICKET_KEY}")
private String tttttt_TICKET_KEY; @Autowired
private RedisUtils redisUtils; @Override
public Boolean check(String param, Integer type) {
// 声明查询条件
User user = new User(); // 1、2、3分别代表username、phone、email
switch (type) {
case 1:
user.setUsername(param);
break;
case 2:
user.setPhone(param);
break;
case 3:
user.setEmail(param);
break; default:
break;
} // 根据条件查询
int count = this.userMapper.selectCount(user); // 如果查询结果count为0表示没有人用过,所以返回true,表示可用
// 如果查询结果count不为0表示有人用过,所以返回false,表示不可用
return count == 0;
} @Override
public User queryUserByTicket(String ticket) {
// 从redis中查询用户的登录信息,是一个json格式的数据
// 需要给redis中的key增加前缀,便于redis数据的维护和管理
String json = this.redisUtils.get(this.tttttt_TICKET_KEY + ticket); // 判断json不为空
if (StringUtils.isNotBlank(json)) {
try {
// 把json格式的数据转为User对象
User user = MAPPER.readValue(json, User.class); // 如果用户请求这个方法,表示用户是活动的,所以需要重置有效时间
this.redisUtils.expire(this.tttttt_TICKET_KEY + ticket, 60 * 60); // 返回user结果
return user;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} // 如果查询结果为空,或者有异常,返回null
return null;
} @Override
public void saveUser(User user) {
// 设置用户的数据
user.setCreated(new Date());
user.setUpdated(user.getCreated()); // 对用户密码进行md5加密
user.setPassword(DigestUtils.md5Hex(user.getPassword())); // 保存用户数据到MySQL
this.userMapper.insert(user); } @Override
public String doLogin(User user) {
// 根据条件从MySQL中查询用户
user.setPassword(DigestUtils.md5Hex(user.getPassword()));
User result = this.userMapper.selectOne(user); // 如果查到的结果不为空,表示用户登录成功
if (result != null) {
// 生成唯一的数,就是ticket
// 利用redis单线程的特点,使用incr每次加一,获取唯一数
// ticket就是redis的唯一数+用户id
String ticket = "" + this.redisUtils.incr("tttttt_TICKET_INCR") + result.getId(); try {
// 把ticket和用户的数据(json数据)放到redis中
this.redisUtils.set(this.tttttt_TICKET_KEY + ticket, MAPPER.writeValueAsString(result), 60 * 60); // 返回ticket
return ticket;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } // 如果查询结果为空或者有异常,返回空
return null;
} }

登录的问题:
1.没有欢迎用户的语句
2.cookie中没有ticket的信息

#配置Nginx反向代理的时候携带域名
proxy_set_header Host $host;

用户注册&单点登录的更多相关文章

  1. 看图理解JWT如何用于单点登录

    单点登录是我比较喜欢的一个技术解决方案,一方面他能够提高产品使用的便利性,另一方面他分离了各个应用都需要的登录服务,对性能以及工作量都有好处.自从上次研究过JWT如何应用于会话管理,加之以前的项目中也 ...

  2. 不需要客户端插件PHP也能实现单点登录

    分析CAS原理,构建PHP单点登录 单点登录(Single Sign On , 简称 SSO )是目前比较流行的服务于企业业务整合的解决方案之一, SSO 使得在多个应用系统中,用户 只需要登录一次就 ...

  3. Shiro与CAS整合实现单点登录

    1.简介 CAS:Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法. Shiro:Apache Shiro是一个Java安全框架,可以帮助我们完成认证.授权.会话管 ...

  4. SpringBoot集成CAS单点登录,SSO单点登录,CAS单点登录(视频资料分享篇)

    单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统. 很早期的公司 ...

  5. 开发SSO单点登录需要注意的问题

      一.单点登录系统开发需要注意的问题     1.单点登录系统需要支持jsonp请求?    单点登录系统主要是向其他系统提供用户身份验证服务,因此需要提供对外接口,而外部系统通过接口访问时,必然涉 ...

  6. 029.[转] SSO单点登录的通用架构实现

    单点登录的通用架构实现 pphh发布于2018年4月26日 http://www.hyhblog.cn/2018/04/26/single_sign_on_arch/ 目录 1. 什么是单点登录 2. ...

  7. 单点登录之CAS原理和实现(转载)

    转载源:https://www.jianshu.com/p/613c615b7ef1 单点登录之CAS原理和实现 来源于作者刘欣的<码农翻身> + 自己的备注理解 这家集团公司财大气粗,竟 ...

  8. JWT--无状态单点登录

    序言 传统的 seesion 认证存在的问题: 1)用户信息存储在内存中,用户规模大之后增加服务器开销:2)由于登录信息存储在内存中,限制了登录机器,不利于分布式站点. JWT JWT无状态登录 常规 ...

  9. 著名ERP厂商的SSO单点登录解决方案介绍一

          SSO英文全称Single Sign On,单点登录.SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.它包括可以将这次主要的登录映射到其他应用中用于同一个用户 ...

随机推荐

  1. 分区工具parted的使用方法

    一.         parted的用途及说明 概括使用说明: parted用于对磁盘(或RAID磁盘)进行分区及管理,与fdisk分区工具相比,支持2TB以上的磁盘分区,并且允许调整分区的大小.   ...

  2. ISO/IEC 9899:2011 条款5——5.1.1 翻译环境

    5.1.1 翻译环境 5.1.1.1程序结构 1.一个C程序不需要一次全被翻译完.程序的文本被保存在本国际标准中被称作为源文件(或预处理文件)的单元里.一个源文件连同所有通过指示符#include所包 ...

  3. springboot 之JPA

    1.添加pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns=" ...

  4. 使用libxml2创建和解析xml文件

    毕业设计需要用到xml文件来组织和存放数据, 对于Linux环境下,有libxml2可供使用. 经过一段时间查询文档和网站, 基本掌握创建xml文档和解析xml的操作, 简单做一下记录. 创建xml ...

  5. 阶段5 3.微服务项目【学成在线】_day18 用户授权_01-用户授权业务流程分析

    1 用户授权业务流程 用户授权的业务流程如下: 业务流程说明如下: 1.用户认证通过,认证服务向浏览器cookie写入token( 身份令牌) 2.前端携带token请求用户中心服务获取jwt令牌 前 ...

  6. 阶段5 3.微服务项目【学成在线】_day17 用户认证 Zuul_07-用户认证-认证服务查询数据库-解析申请令牌错误信息

    1.2.5.4 解析申请令牌错误信息 当账号输入错误应该返回用户不存在的信息,当密码错误要返回用户名或密码错误信息,业务流程图如下: 修改申请令牌的程序解析返回的错误: 由于restTemplate收 ...

  7. 第十二章 与Spring集成——《跟我学Shiro》

    转发:https://www.iteye.com/blog/jinnianshilongnian-2029717 目录贴:跟我学Shiro目录贴 Shiro的组件都是JavaBean/POJO式的组件 ...

  8. sonar:soanrqube接口api

    背景: jenkins+sonar集成了代码扫描,但是发出的邮件不管项目质量是通过还是失败,每次邮件的标题都是jenkins的构建状态,所以需要获取sonar中该项目的扫描结果. 解决: 在sonar ...

  9. WebStorm 2018.2安装激活教程

    1.下载解压,得到jetbrains webstorm 2018.2主程序,破解文件和中文语言包: 2.运行“WebStorm-2018.2.exe”开始安装,默认安装目录[C:\Program Fi ...

  10. [转载]Oracle中TO_NUMBER()函数的用法

    1 用法简介TO_NUMBER函数()是Oracle中常用的类型转换函数之一,主要是将字符串转换为数值型的格式,与TO_CHAR()函数的作用正好相反. To_number函数的格式如下: To_nu ...