1. 程式人生 > >【Java】單點登入

【Java】單點登入

【單點登入】

       單點登入SSO(Single Sign On)。SSO是在多個應用系統中,使用者只需要登入一次就可以訪問所有相互信任的應用系統。它包括可以將這次主要的登入對映到其他應用中用於同一個使用者的登入的機制。

       畫了一張圖,大概描述下單點登入的過程。



【SSM+Dubbo+Zookeeper下實現】


Dao層
       只涉及到tb_User單張表的查詢操作,Dao層使用Mybatis的逆向工程程式碼

Interface層
import cn.e3mall.common.utils.E3Result;


public interface LoginService {
	
	E3Result userLogin(String username,String password);
}

Service層

       使用者登入資訊,每一條使用者資訊的sessionId存入cookie中,通過cookie獲取sessionId,使用UUID作為sessionId。token本質上就是sessionId。

       設定session過期時間,session過期時間在 resource.properties裡配置。
#session 的過期時間
SESSION_EXPIRE=1800
       在需要用到session過期時間的方法前添加註解。   
@Value ("${SESSION_EXPIRE}")
private Integer SESSION_EXPIRE;

       程式碼中設定session過期時間用到了redis。   

jedisClient.expire("SESSION:" + token, SESSION_EXPIRE);

Code:
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 cn.e3mall.common.jedis.JedisClient;
import cn.e3mall.common.utils.E3Result;
import cn.e3mall.common.utils.JsonUtils;
import cn.e3mall.mapper.TbUserMapper;
import cn.e3mall.pojo.TbUser;
import cn.e3mall.pojo.TbUserExample;
import cn.e3mall.pojo.TbUserExample.Criteria;
import cn.e3mall.sso.service.LoginService;


/**
 * 
 * @author 璐
 *
 */


@Service
public class LoginServiceImpl implements LoginService {


	@Autowired 
	private TbUserMapper userMapper;
	@Autowired
	private JedisClient jedisClient;
	@Value ("${SESSION_EXPIRE}")
	private Integer SESSION_EXPIRE;
	
	
	@Override
	public E3Result userLogin(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, "使用者名稱或密碼錯誤");
		}
		//2.取使用者資訊
		TbUser user = list.get(0);
		//判斷密碼是否正確
		if(!DigestUtils.md5DigestAsHex(password.getBytes()).equals(user.getPassword())){
			return E3Result.build(400, "使用者名稱或密碼錯誤");
		}
		
		//3.正確生成token
		String token = UUID.randomUUID().toString();
		
		//4.使用者資訊寫入redis,key:token ,value:使用者資訊
		user.setPassword(null);
		jedisClient.set("SESSION:" + token, JsonUtils.objectToJson(user));
		
		//5.設定session過期時間
		jedisClient.expire("SESSION:" + token, SESSION_EXPIRE);
		//6.返回token
		return E3Result.ok(token);
	}


}
       Service寫好之後,在applicationContext-service.xml 裡暴露服務介面。

Controller層

       系統拆分成了很多不同的工程,實現登入要做到跨域名訪問,Cookie是域名隔離的,可以跨域名訪問。所以我們在common裡引入了一個cookie的工具類。


1.cookie中儲存token的key存放在resource.properties裡
#cookie中儲存token的key
TOKEN_KEY=token

2.Controller 裡的在引用 value的標籤
@Value("${TOKEN_KEY}")
	private String TOKEN_KEY;

3.將token寫入cookie。

CookieUtils.setCookie(request, response, TOKEN_KEY, token);

 Code:

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


import cn.e3mall.common.utils.CookieUtils;
import cn.e3mall.common.utils.E3Result;
import cn.e3mall.sso.service.LoginService;


@Controller
public class LoginController {


	@Autowired 
	private LoginService  loginService;
	
	@Value("${TOKEN_KEY}")
	private String TOKEN_KEY;
	
	@RequestMapping("/page/login")
	public String showLogin(){
		return "login";
	}
	
	@RequestMapping(value="/user/login",method=RequestMethod.POST)
	@ResponseBody
	public E3Result login(String username,String password,
			HttpServletRequest request,HttpServletResponse response){
		
		//呼叫service的使用者登入方法
		E3Result e3Result = loginService.userLogin(username, password);
		//判斷是否登入成功
		if(e3Result.getStatus() == 200){
			String token=e3Result.getData().toString();
			//登入成功需要把token寫入cookie
			CookieUtils.setCookie(request, response, TOKEN_KEY, token);
			
		}
		return e3Result;
	}
}
       Controller方法寫好之後,要在springmvc.xml 檔案裡引用Dubbo服務。

【小結】

        單點登入的大致實現過程做了一個小結,還有待深入學習。以上如有錯誤請各位看官評論指出~