淘淘商城59-SSO单点登录系统之用户登录接口开发

版权声明:本文为博主原创文章,如有转载请注明出处,谢谢。 https://blog.csdn.net/pdsu161530247/article/details/82183424

目录

1.分析接口文档

2.登录接口实现

2.1登录分析

2.2服务层

2.2.1dao层

2.2.2service层

2.3表现层

2.3.1引入服务

2.3.2controller

3.测试访问


1.分析接口文档

请求的url:/user/login

请求的方法:POST

参数:username、password。

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

2.登录接口实现

2.1登录分析

看接口文档感觉登录比较简单....其实并不是这样。

下面这个图是单点登录系统登录时,登录要经历的完整流程图。

目前只需要实现到,将key:token,value:user以String类型存入redis,将token存入cookie中即可。

也就是这部分:

登录的处理流程:

  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.taotao.com\sso.taotao.com\order.taotao.com,可以使用工具类。
  8. Cookie的有效期。关闭浏览器失效。
  9. 登录成功,进入portal首页。

2.2服务层

2.2.1dao层

查询tb_user表。直接使用逆向工程。

2.2.2service层

service接口

在taotao-sso-interface创建登录接口UserLoginService

/**
	 * 用户登录,生成token作为key,value=user
	 * @param username
	 * @param password
	 * @return
	 */
	TaotaoResult login(String username,String password);

service实现类

  1. 判断用户名密码是否正确。
  2. 登录成功后生成token。Token相当于原来的jsessionid,字符串,可以使用uuid。
  3. 把用户信息保存到redis。Key就是token,value就是TbUser对象转换成json。
  4. 使用String类型保存Session信息。可以使用“前缀:token”为key
  5. 设置key的过期时间。模拟Session的过期时间。一般半个小时。
  6. 返回TaotaoResult包装token。

在taotao-sso-service创建实现类UserLoginServiceImpl

使用"前缀:token"作为key,可以很好的分类redis中的存放的数据。前缀和过期时间放在properties文件中

package com.taotao.sso.service.impl;

import java.util.List;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.taotao.common.pojo.TaotaoResult;
import com.taotao.common.utils.JsonUtils;
import com.taotao.mapper.TbUserMapper;
import com.taotao.pojo.TbUser;
import com.taotao.pojo.TbUserExample;
import com.taotao.pojo.TbUserExample.Criteria;
import com.taotao.sso.jedis.JedisClient;
import com.taotao.sso.service.UserLoginService;
@Service
public class UserLoginServiceImpl implements UserLoginService {
	
	@Autowired
	private TbUserMapper userMapper;
	@Autowired
	private JedisClient jedisClient;
	@Value("${USER_SESSION}")
	private String USER_SESSION;
	@Value("${SESSION_EXPIRE_TIME}")
	private Integer SESSION_EXPIRE_TIME;
	/**
	 * 校验用户名、密码。校验成功后生产token
	 * 把token作为key,将用户信息缓存到redis中,并设置过期时间
	 */
	@Override
	public TaotaoResult login(String username, String password) {
		//1.校验用户名、密码
		//1.1校验用户名是否存在
		TbUserExample tbUserExample = new TbUserExample();
		Criteria criteria = tbUserExample.createCriteria();
		criteria.andUsernameEqualTo(username);
		List<TbUser> list = userMapper.selectByExample(tbUserExample);
		if(list.size()==0 ||list==null) {
			return TaotaoResult.build(400, "用户名或者密码错误");
		}
		//1.2校验密码是否正确
		TbUser tbUser = list.get(0);
		if(!tbUser.getPassword().equals(DigestUtils.md5DigestAsHex(password.getBytes()))) {
			return TaotaoResult.build(400, "用户名或者密码错误");
		}
		//2.校验成功后生产token
		String token = UUID.randomUUID().toString();
		//3.把用户信息保存到redis。Key就是token,value就是TbUser对象转换成json。
		tbUser.setPassword(null);
		String key = USER_SESSION + ":" +token;
		jedisClient.set(key, JsonUtils.objectToJson(tbUser));
		//4.设置token过期时间
		jedisClient.expire(key, SESSION_EXPIRE_TIME);
		//5.返回token
		return TaotaoResult.ok(token);
	}
}

resource.properties配置文件

创建resource.properties放在taotao-sso-service的src/main/resources下

#redis中缓存用户信息key的前缀
USER_SESSION=SESSION
#session存活时间
SESSION_EXPIRE_TIME=1800

发布服务

在applicationContext-service.xml中发布服务

<dubbo:service interface="com.taotao.sso.service.UserLoginService" ref="userLoginServiceImpl" timeout="300000"/>

2.3表现层

2.3.1引入服务

在taotao-sso-web的springmvc.xml中引入service的服务

<dubbo:reference interface="com.taotao.sso.service.UserLoginService" id="userLoginService" timeout="300000" />
    

2.3.2controller

在这里使用了一个CookieUtils用来专门将token存放到cookie中,cookie需要跨域。

将CookieUtils放到taotao-common里面

package com.taotao.common.utils;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * 
 * Cookie 工具类
 *
 */
public final class CookieUtils {

    /**
     * 得到Cookie的值, 不编码
     * 
     * @param request
     * @param cookieName
     * @return
     */
    public static String getCookieValue(HttpServletRequest request, String cookieName) {
        return getCookieValue(request, cookieName, false);
    }

    /**
     * 得到Cookie的值,
     * 
     * @param request
     * @param cookieName
     * @return
     */
    public static String getCookieValue(HttpServletRequest request, String cookieName, boolean isDecoder) {
        Cookie[] cookieList = request.getCookies();
        if (cookieList == null || cookieName == null) {
            return null;
        }
        String retValue = null;
        try {
            for (int i = 0; i < cookieList.length; i++) {
                if (cookieList[i].getName().equals(cookieName)) {
                    if (isDecoder) {
                        retValue = URLDecoder.decode(cookieList[i].getValue(), "UTF-8");
                    } else {
                        retValue = cookieList[i].getValue();
                    }
                    break;
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return retValue;
    }

    /**
     * 得到Cookie的值,
     * 
     * @param request
     * @param cookieName
     * @return
     */
    public static String getCookieValue(HttpServletRequest request, String cookieName, String encodeString) {
        Cookie[] cookieList = request.getCookies();
        if (cookieList == null || cookieName == null) {
            return null;
        }
        String retValue = null;
        try {
            for (int i = 0; i < cookieList.length; i++) {
                if (cookieList[i].getName().equals(cookieName)) {
                    retValue = URLDecoder.decode(cookieList[i].getValue(), encodeString);
                    break;
                }
            }
        } catch (UnsupportedEncodingException e) {
        	 e.printStackTrace();
        }
        return retValue;
    }

    /**
     * 设置Cookie的值 不设置生效时间默认浏览器关闭即失效,也不编码
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue) {
        setCookie(request, response, cookieName, cookieValue, -1);
    }

    /**
     * 设置Cookie的值 在指定时间内生效,但不编码
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, int cookieMaxage) {
        setCookie(request, response, cookieName, cookieValue, cookieMaxage, false);
    }

    /**
     * 设置Cookie的值 不设置生效时间,但编码
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, boolean isEncode) {
        setCookie(request, response, cookieName, cookieValue, -1, isEncode);
    }

    /**
     * 设置Cookie的值 在指定时间内生效, 编码参数
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, int cookieMaxage, boolean isEncode) {
        doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, isEncode);
    }

    /**
     * 设置Cookie的值 在指定时间内生效, 编码参数(指定编码)
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
            String cookieValue, int cookieMaxage, String encodeString) {
        doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, encodeString);
    }

    /**
     * 删除Cookie带cookie域名
     */
    public static void deleteCookie(HttpServletRequest request, HttpServletResponse response,
            String cookieName) {
        doSetCookie(request, response, cookieName, "", -1, false);
    }

    /**
     * 设置Cookie的值,并使其在指定时间内生效
     * 
     * @param cookieMaxage cookie生效的最大秒数
     */
    private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
            String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) {
        try {
            if (cookieValue == null) {
                cookieValue = "";
            } else if (isEncode) {
                cookieValue = URLEncoder.encode(cookieValue, "utf-8");
            }
            Cookie cookie = new Cookie(cookieName, cookieValue);
            if (cookieMaxage > 0)
                cookie.setMaxAge(cookieMaxage);
            if (null != request) {// 设置域名的cookie
            	String domainName = getDomainName(request);
            	//System.out.println(domainName);
                if (!"localhost".equals(domainName)) {
                	cookie.setDomain(domainName);
                }
            }
            cookie.setPath("/");
            response.addCookie(cookie);
        } catch (Exception e) {
        	 e.printStackTrace();
        }
    }

    /**
     * 设置Cookie的值,并使其在指定时间内生效
     * 
     * @param cookieMaxage cookie生效的最大秒数
     */
    private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
            String cookieName, String cookieValue, int cookieMaxage, String encodeString) {
        try {
            if (cookieValue == null) {
                cookieValue = "";
            } else {
                cookieValue = URLEncoder.encode(cookieValue, encodeString);
            }
            Cookie cookie = new Cookie(cookieName, cookieValue);
            if (cookieMaxage > 0)
                cookie.setMaxAge(cookieMaxage);
            if (null != request) {// 设置域名的cookie
            	String domainName = getDomainName(request);
            	System.out.println(domainName);
                if (!"localhost".equals(domainName)) {
                	cookie.setDomain(domainName);
                }
            }
            cookie.setPath("/");
            response.addCookie(cookie);
        } catch (Exception e) {
        	 e.printStackTrace();
        }
    }

    /**
     * 得到cookie的域名
     */
    private static final String getDomainName(HttpServletRequest request) {
        String domainName = null;

        String serverName = request.getRequestURL().toString();
        if (serverName == null || serverName.equals("")) {
            domainName = "";
        } else {
            serverName = serverName.toLowerCase();
            serverName = serverName.substring(7);
            final int end = serverName.indexOf("/");
            serverName = serverName.substring(0, end);
            final String[] domains = serverName.split("\\.");
            int len = domains.length;
            if (len > 3) {
                // www.xxx.com.cn
                domainName = "." + domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1];
            } else if (len <= 3 && len > 1) {
                // xxx.com or xxx.cn
                domainName = "." + domains[len - 2] + "." + domains[len - 1];
            } else {
                domainName = serverName;
            }
        }

        if (domainName != null && domainName.indexOf(":") > 0) {
            String[] ary = domainName.split("\\:");
            domainName = ary[0];
        }
        return domainName;
    }

}

在taotao-sso-web下创建UserLoginController。

设置cookie时需要设置一个name,将这个name放到resource.properties

package com.taotao.sso.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.taotao.common.pojo.TaotaoResult;
import com.taotao.common.utils.CookieUtils;
import com.taotao.sso.service.UserLoginService;

@Controller
public class UserLoginController {

	@Autowired
	private UserLoginService userLoginService;
	@Value("${COOKIE_TOKEN_KEY}")
	private String COOKIE_TOKEN_KEY;
	/**
	 * 接收username、password,调用service服务
	 * 将返回的token存入cookie中
	 * @param username
	 * @param password
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/user/login", method = RequestMethod.POST)
	@ResponseBody
	public TaotaoResult login(String username, String password, HttpServletRequest request,
			HttpServletResponse response) {
		// 1、接收两个参数。
		// 2、调用Service进行登录。
		TaotaoResult result = userLoginService.login(username, password);
		// 3、从返回结果中取token,写入cookie。Cookie要跨域。
		if(result.getStatus() == 200) {
			String token = result.getData().toString();
			CookieUtils.setCookie(request, response, COOKIE_TOKEN_KEY, token);
		}
		// 4、响应数据。Json数据。TaotaoResult,其中包含Token。
		return result;
	}
}

resource.properties文件

COOKIE_TOKEN_KEY=COOKIE_TOKEN_KEY

3.测试访问

安装taotao-common、taotao-sso,启动taotao-sso、taotao-sso-web

我们使用数据库中已存在的username=123465、password=123456

 返回了我们生成的token

我们查看redis,发现用户信息已经存入redis中

猜你喜欢

转载自blog.csdn.net/pdsu161530247/article/details/82183424