欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JAVAEE——宜立方商城11:sso登录注册功能实现、通过token获得用户信息、Ajax跨域请求(jsonp)

程序员文章站 2022-04-24 07:53:58
1. 学习计划 第十一天: 1、sso注册功能实现 2、sso登录功能实现 3、通过token获得用户信息 4、Ajax跨域请求(jsonp) 2. Sso系统工程搭建 需要创建一个sso服务工程,可以参考e3-manager创建。 e3-sso(pom聚合工程) |--e3-sso-interfa ......

1. 学习计划

第十一天:

1、sso注册功能实现

2、sso登录功能实现

3、通过token获得用户信息

4、Ajax跨域请求(jsonp

2. Sso系统工程搭建

 JAVAEE——宜立方商城11:sso登录注册功能实现、通过token获得用户信息、Ajax跨域请求(jsonp)

 

 

需要创建一个sso服务工程,可以参考e3-manager创建。

e3-ssopom聚合工程)

   |--e3-sso-interfacejar

   |--e3-sso-Servicewar

e3-sso-web

3. 服务接口实现

3.1. 检查数据是否可用

3.1.1. 功能分析

请求的url/user/check/{param}/{type}

参数:从url中取参数1String param(要校验的数据)2Integer type(校验的数据类型)

响应的数据:json数据。e3Result,封装的数据校验的结果true:成功false:失败。

业务逻辑:

1、tb_user表中查询数据

2、查询条件根据参数动态生成。

3、判断查询结果,如果查询到数据返回false

4、如果没有返回true

5、使用e3Result包装,并返回。

 

3.1.2. Dao

tb_user表查询。可以使用逆向工程。

3.1.3. Service

参数:

1、要校验的数据:String param

2、数据类型:int type123分别代表usernamephoneemail

返回值:e3Result

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private TbUserMapper userMapper;
    
    @Override
    public e3Result checkData(String param, int type) {
        // 1、从tb_user表中查询数据
        TbUserExample example = new TbUserExample();
        Criteria criteria = example.createCriteria();
        // 2、查询条件根据参数动态生成。
        //1、2、3分别代表username、phone、email
        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);
        // 3、判断查询结果,如果查询到数据返回false。
        if (list == null || list.size() == 0) {
            // 4、如果没有返回true。
            return e3Result.ok(true);
        } 
        // 5、使用e3Result包装,并返回。
        return e3Result.ok(false);
    }

}

 


发布服务
 

 

 

3.1.4. 表现层

需要在e3-sso-web中实现。

引用服务

Controller

请求的url/user/check/{param}/{type}

参数:从url中取参数1String param(要校验的数据)2Integer type(校验的数据类型)

响应的数据:json数据。e3Result,封装的数据校验的结果true:成功false:失败。

@Controller
public class UserController {

    @Autowired
    private UserService userService;
    
    @RequestMapping("/user/check/{param}/{type}")
    @ResponseBody
    public e3Result checkData(@PathVariable String param, @PathVariable Integer type) {
        e3Result e3Result = userService.checkData(param, type);
        return e3Result;
    }
}

 


3.2.1. 功能分析
3.2. 用户注册

请求的url/user/register

参数:表单的数据:usernamepasswordphoneemail

返回值:json数据。e3Result

接收参数:使用TbUser对象接收。

请求的方法:post

业务逻辑:

1、使用TbUser接收提交的请求。

2、补全TbUser其他属性。

3、密码要进行MD5加密。

4、把用户信息插入到数据库中。

5、返回e3Result

 

3.2.2. Dao

可以使用逆向工程。

3.2.3. Service

参数:TbUser

返回值:e3Result

 

@Override
    public e3Result createUser(TbUser user) {
        // 1、使用TbUser接收提交的请求。
        
        if (StringUtils.isBlank(user.getUsername())) {
            return e3Result.build(400, "用户名不能为空");
        }
        if (StringUtils.isBlank(user.getPassword())) {
            return e3Result.build(400, "密码不能为空");
        }
        //校验数据是否可用
        e3Result result = checkData(user.getUsername(), 1);
        if (!(boolean) result.getData()) {
            return e3Result.build(400, "此用户名已经被使用");
        }
        //校验电话是否可以
        if (StringUtils.isNotBlank(user.getPhone())) {
            result = checkData(user.getPhone(), 2);
            if (!(boolean) result.getData()) {
                return e3Result.build(400, "此手机号已经被使用");
            }
        }
        //校验email是否可用
        if (StringUtils.isNotBlank(user.getEmail())) {
            result = checkData(user.getEmail(), 3);
            if (!(boolean) result.getData()) {
                return e3Result.build(400, "此邮件地址已经被使用");
            }
        }
        // 2、补全TbUser其他属性。
        user.setCreated(new Date());
        user.setUpdated(new Date());
        // 3、密码要进行MD5加密。
        String md5Pass = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
        user.setPassword(md5Pass);
        // 4、把用户信息插入到数据库中。
        userMapper.insert(user);
        // 5、返回e3Result。
        return e3Result.ok();
    }

 


 发布服务

3.2.4. 表现层

引用服务。

 

Controller

请求的url/user/register

参数:表单的数据:usernamepasswordphoneemail

返回值:json数据。e3Result

接收参数:使用TbUser对象接收。

请求的方法:post

@RequestMapping(value="/user/register", method=RequestMethod.POST)
    @ResponseBody
    public e3Result register(TbUser user) {
        e3Result result = userService.createUser(user);
        return result;
    }

 


3.2.5. 测试
 

可以使用restclient-ui-3.5-jar-with-dependencies.jar测试接口。

 JAVAEE——宜立方商城11:sso登录注册功能实现、通过token获得用户信息、Ajax跨域请求(jsonp)

 

表单提交的content-typeapplication/x-www-form-urlencoded

3.3. 用户登录

3.3.1. 功能分析

请求的url/user/login

请求的方法:POST

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

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

业务逻辑:

登录的业务流程:

 JAVAEE——宜立方商城11:sso登录注册功能实现、通过token获得用户信息、Ajax跨域请求(jsonp)

 

 

登录的处理流程:

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

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

3、把用户信息保存到redisKey就是tokenvalue就是TbUser对象转换成json

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

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

6、token写入cookie中。

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

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

9、登录成功。

 

3.3.2. Dao

查询tb_user表。单表查询。可以使用逆向工程。

 

3.3.3. Service

参数:

1、用户名:String username

2、密码:String password

返回值:e3Result,包装token

业务逻辑:

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

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

3、把用户信息保存到redisKey就是tokenvalue就是TbUser对象转换成json

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

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

6、返回e3Result包装token

@Override
    public e3Result 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 e3Result.build(400, "用户名或密码错误");
        }
        TbUser user = list.get(0);
        //校验密码
        if (!user.getPassword().equals(DigestUtils.md5DigestAsHex(password.getBytes()))) {
            return e3Result.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、返回e3Result包装token。
        return e3Result.ok(token);
    }

 


 发布服务

3.3.4. 表现层

引用服务:

 

Controller

请求的url/user/login

请求的方法:POST

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

HttpServletRequestHttpServletResponse

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

业务逻辑:

1、接收两个参数。

2、调用Service进行登录。

3、从返回结果中取token,写入cookieCookie要跨域。

Cookie二级域名跨域需要设置:

1setDomain,设置一级域名:

.itcatst.cn

.e3.com

.e3.com.cn

2setPath。设置为“/

 

工具类放到e3-common工程中。

4、响应数据。Json数据。e3Result,其中包含Token

 

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

 


3.4. 
通过token查询用户信息 

3.4.1. 功能分析

请求的url/user/token/{token}

参数:String token需要从url中取。

返回值:json数据。使用e3Result包装Tbuser对象。

业务逻辑:

1、url中取参数。

2、根据token查询redis

3、如果查询不到数据。返回用户已经过期。

4、如果查询到数据,说明用户已经登录。

5、需要重置key的过期时间。

6、json数据转换成TbUser对象,然后使用e3Result包装并返回。

 

3.4.2. Dao

使用JedisClient对象。

 

3.4.3. Service

参数:String token

返回值:e3Result

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

 


3.4.4. 表现层
 

请求的url/user/token/{token}

参数:String token需要从url中取。

返回值:json数据。使用e3Result包装Tbuser对象。

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

 


作业
3.4.5. 安全退出

需要根据token删除redis中的key

 

4. 登录注册页面实现

4.1. 注册功能

第一步:把静态页面添加到工程中。

第二步:展示页面。

请求的url

登录:/page/login

注册:/page/register

参数:无

返回结果:逻辑视图String

 

@Controller
public class PageController {

    @RequestMapping("/page/register")
    public String showRegister() {
        return "register";
    }
    
    @RequestMapping("/page/login")
    public String showLogin() {
        return "login";
    }
}

 

 


第三步:
js处理。 

 JAVAEE——宜立方商城11:sso登录注册功能实现、通过token获得用户信息、Ajax跨域请求(jsonp)

 

 

4.2. 登录功能

参考login.jsp

 

5. 登录注册页面整合首页

5.1. 首页跳转到登录、注册页面

 JAVAEE——宜立方商城11:sso登录注册功能实现、通过token获得用户信息、Ajax跨域请求(jsonp)

 

 

5.2. 首页展示用户名

1、当用户登录成功后,在cookie中有token信息。

2、cookie中取token根据token查询用户信息。

3、把用户名展示到首页。

 

方案一:在Controller中取cookie中的token数据,调用sso服务查询用户信息。

方案二:当页面加载完成后使用jstoken的数据,使用ajax请求查询用户信息。

 

问题:服务接口在sso系统中。Sso.e3.com(localhost:8088),在首页显示用户名称,首页的域名是www.e3.com(localhost:8082),使用ajax请求跨域了。

 

Js不可以跨域请求数据。

什么是跨域:

1、域名不同

2、域名相同端口不同。

 

解决js的跨域问题可以使用jsonp

 

Jsonp不是新技术,跨域的解决方案。使用js的特性绕过跨域请求。Js可以跨域加载js文件。

 

 

5.3. Jsonp原理

 JAVAEE——宜立方商城11:sso登录注册功能实现、通过token获得用户信息、Ajax跨域请求(jsonp)

 

5.4. Json实现

5.4.1. 客户端

使用jQuery

 

5.4.2. 服务端

1、接收callback参数,取回调的js的方法名。

2、业务逻辑处理。

3、响应结果,拼接一个js语句。

方法一:

 JAVAEE——宜立方商城11:sso登录注册功能实现、通过token获得用户信息、Ajax跨域请求(jsonp)

 

方法二:

 JAVAEE——宜立方商城11:sso登录注册功能实现、通过token获得用户信息、Ajax跨域请求(jsonp)