首先感謝xxl-sso開源項目,傳送門 xxl-soo官網.
整合xxl-sso
- springboot項目內建xxl-sso
-
- 前後端一體的項目內建xxl-sso
-
- 前後端分離內建xxl-sso
springboot項目內建xxl-sso
前言:由于我們公司項目比較多,登陸基本上都是工号加密碼,是以想做一個單點系統,登陸A系統之後就可以直接進入其他任意相關系統無需登陸,一個系統退出,所有系統退出,這裡找了很多資料和部落格,最終選擇xxl-sso做內建
大家把項目下載下傳下來後更xxl-sso-server中的application.properties檔案
### web
server.port=8080
server.servlet.context-path=/xxl-sso-server
### resources
spring.mvc.servlet.load-on-startup=0
spring.mvc.static-path-pattern=/static/**
spring.resources.static-locations=classpath:/static/
### freemarker
spring.freemarker.templateLoaderPath=classpath:/templates/
spring.freemarker.suffix=.ftl
spring.freemarker.charset=UTF-8
spring.freemarker.request-context-attribute=request
spring.freemarker.settings.number_format=0.##########
### xxl-sso
xxl.sso.redis.address=redis://127.0.0.1:6379
xxl.sso.redis.expire.minute=1440
主要更改一下這個redis的位址即可
他這邊還給了兩個執行個體項目xxl-sso-web-sample-springboot和xxl-sso-token-sample-springboot,我這邊使用xxl-sso-web-sample-springboot做的測試,先更改application.properties檔案
### web
server.port=8082
server.servlet.context-path=/xxl-sso-web-sample-springboot
### resources
spring.mvc.servlet.load-on-startup=0
spring.mvc.static-path-pattern=/static/**
spring.resources.static-locations=classpath:/static/
### freemarker
spring.freemarker.templateLoaderPath=classpath:/templates/
spring.freemarker.suffix=.ftl
spring.freemarker.charset=UTF-8
spring.freemarker.request-context-attribute=request
spring.freemarker.settings.number_format=0.##########
### xxl-sso
xxl.sso.server=http://localhost:8080/xxl-sso-server
xxl.sso.logout.path=/logout
xxl-sso.excluded.paths=
xxl.sso.redis.address=redis://127.0.0.1:6379
這裡主要更改xxl.sso.server,這個改成你xxl-sso-server的啟動位址即可,還需改一下redis位址
這裡啟動項目一個8080的http://localhost:8080/xxl-sso-server/login,一個8081的http://localhost:8081/xxl-sso-web-sample-springboot
在8080未登陸情況下,8081直接登陸會跳轉至8080登陸頁面,任意一個系統登陸成功後,同浏覽器直接可以輸入其他系統位址,無需登陸,一個系統退出,所有系統都退出
這裡基本上按照dome走就搭建完畢了,接下來進入我們自己的項目
前後端一體的項目內建xxl-sso
上一步中的http://localhost:8081/xxl-sso-web-sample-springboot就是一個springboot項目這裡我們內建到自己項目中去
首先添加maven依賴,pom中添加,我這裡用到springboot版本是>2.3.0的版本
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-sso-core</artifactId>
<version>1.1.0</version>
</dependency>
配置application.properties檔案中添加xxl-sso相關配置
xxl.sso.server=http://localhost:8080/xxl-sso-server
xxl.sso.logout.path=/logout
xxl-sso.excluded.paths=
xxl.sso.redis.address=redis://127.0.0.1:6379
這裡xxl-sso.excluded.paths可以配置無需攔截的一些路徑,如檔案下載下傳,這種公共對外接口無需登陸的路徑,多個用,隔開
添加XxlSsoConfig.java配置類
package com.xxl;
import com.xxl.sso.core.conf.Conf;
import com.xxl.sso.core.filter.XxlSsoWebFilter;
import com.xxl.sso.core.util.JedisUtil;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author xuxueli 2018-11-15
*/
@Configuration
public class XxlSsoConfig implements DisposableBean {
@Value("${xxl.sso.server}")
private String xxlSsoServer;
@Value("${xxl.sso.logout.path}")
private String xxlSsoLogoutPath;
@Value("${xxl-sso.excluded.paths}")
private String xxlSsoExcludedPaths;
@Value("${xxl.sso.redis.address}")
private String xxlSsoRedisAddress;
@Bean
public FilterRegistrationBean xxlSsoFilterRegistration() {
// xxl-sso, redis init
JedisUtil.init(xxlSsoRedisAddress);
// xxl-sso, filter init
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setName("XxlSsoWebFilter");
registration.setOrder(1);
registration.addUrlPatterns("/*");
registration.setFilter(new XxlSsoWebFilter());
registration.addInitParameter(Conf.SSO_SERVER, xxlSsoServer);
registration.addInitParameter(Conf.SSO_LOGOUT_PATH, xxlSsoLogoutPath);
registration.addInitParameter(Conf.SSO_EXCLUDED_PATHS, xxlSsoExcludedPaths);
return registration;
}
@Override
public void destroy() throws Exception {
// xxl-sso, redis close
JedisUtil.close();
}
}
注意,官方給的模闆中使用者名密碼是寫死在背景的,實際我們應用中需要更改為從資料庫擷取,可以在xxl-sso-server中更改UserServiceImpl,我這邊做測試就自己先加了一個使用者名密碼
我這邊是在控制器裡面寫了個入口,用重定向做了跳轉,跳轉到我自己的其他項目的首頁,因為這個項目中在session中存了使用者資訊,是以我這邊在這裡跳轉前進行了存儲,因為這裡是做示範,我這邊在xxl-sso-server存的是寫死的使用者名和密碼,這邊擷取到後再去資料庫根據id把使用者資訊查詢到存儲全量資訊
@RequestMapping("/")
public void index(Model model, HttpServletRequest request,HttpServletResponse response) {
XxlSsoUser xxlUser = (XxlSsoUser) request.getAttribute(Conf.SSO_USER);
request.getSession().setAttribute(ClomnUtil.USERKEY,loginServiceipml.loginByid(Integer.parseInt(xxlUser.getUserid())));
String uri = request.getScheme() + "://" +
request.getServerName() +
":" + request.getLocalPort() +"/menu";
try {
response.sendRedirect(uri);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
上面這一步其實是登陸後做跳轉用的,相當于我們輸入http://localhost:項目端口/,會直接跳轉到8080的xxs-sso中去先登陸,登陸完成後調用我上面的方案去跳轉到我的項目首頁,加這一步的目的是為了存儲我的使用者資訊到session,友善我後續使用這個使用者資訊
退出的時候同樣,情況我們的session和全局token資訊
@GetMapping(value="/loginout")
@ResponseBody
public int getLoginPageOut(HttpServletRequest request) {
request.getSession().removeAttribute(ClomnUtil.USERKEY);
SsoTokenLoginHelper.logout(CookieUtil.getValue(request, "xxl_sso_sessionid"));
return 200;
}
這裡的傳回資訊其實沒用,因為調用SsoTokenLoginHelper.logout後會自動調用一個重定向方案跳轉到的登陸界面
這一套springboot一體的就完成了,基本上改動很小,改一下配置檔案,加一個配置類,登陸、退出的時候根據自己的需求去做特殊處理就完了
前後端分離內建xxl-sso
我這邊還有個項目是使用vue前後端分離的,剛開始內建的時候一直內建不了,因為涉及到跨域,前後端分離登一大堆問題,好在後來都解決了,下面開始
首先還是一樣後端更改application.properties,添加配置類XxlSsoConfig,這裡不在重複了,這裡說一下我的方案
因為前後端分離的項目,我們前端統一登陸後時沒辦法直接跳轉到VUE的前端頁面的,即時跳過去我的相關token也沒法給到vue頁面,這裡統一登陸完成後先進入後端,從後端再跳到登陸頁面(也可以是其他空白頁面),在這個頁面初始化的時候去把相關資訊存取到前台的公共變量中,在ajax中去設定統一攔截,請求前去統一加xxl_sso_sessionid和token,一定要加xxl_sso_sessionid不然背景會攔截,但無法跳轉到登陸,頁面會一直停在這裡的,上代碼
@RequestMapping("/loginSinge")
public void index(Model model, HttpServletRequest request,HttpServletResponse response) {
XxlSsoUser xxlUser = (XxlSsoUser) request.getAttribute(Conf.SSO_USER);
String xxl_sso_sessionid = CookieUtil.getValue(request, "xxl_sso_sessionid");
sysUserTokenService.createToken(Long.parseLong(xxlUser.getUserid()),xxl_sso_sessionid);
String uri = request.getScheme() + "://localhost:8001"
+"/login#/login?token="+xxl_sso_sessionid;
try {
response.sendRedirect(uri);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 退出
*/
@PostMapping("/sys/logout")
public R logout(HttpServletRequest request) {
sysUserTokenService.logout(getUserId());
SsoTokenLoginHelper.logout(CookieUtil.getValue(request, "token"));
return R.ok();
}
這裡//localhost:8001是前端項目的位址,這裡友善示範我就先寫死了,這裡sysUserTokenService.createToken(Long.parseLong(xxlUser.getUserid()),xxl_sso_sessionid);是我本地生成token的方法,我這邊為了偷懶直接用xxl-sso的sessionid作為我的token,這裡比較麻煩,如果自己生成的話,後面可以重定向的時候?token="+xxl_sso_sessionid;需要再加一個你自己的token,退出也一樣,先清自己的token,再清全局token,清完後會自動跳轉到登陸
vue頁面前端再created的時候調用this.loginSing()
loginSing () {
if(this.$route.query.token!=null){
this.$cookie.set('token', this.$route.query.token)
this.$router.replace({ name: 'home' })
}else{
window.location.href='http://localhost:8080/xxl-sso-server/'
}
}
這邊直接從請求中把token擷取到存到前台全局變量中
在httpRequest.js中添加
import Vue from 'vue'
import axios from 'axios'
const http = axios.create({
timeout: 1000 * 30,
withCredentials: true,
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
})
/**
* 請求攔截
*/
http.interceptors.request.use(config => {
return config
}, error => {
return Promise.reject(error)
})
主要是xxl_sso_sessionid這個全局token帶上即可,然後通路統一登陸入口,登陸成功通路我們自己項目的loginSinge方法,會跳登陸頁面然後立即跳到首頁,這個很快的,我這個方案是把token放到請求路徑中,通過 this.$route.query去擷取,可能有點不安全,但功能确實是實作了。另外他這個首頁和登陸大家也可以根據需求去更改一下,這個樣式…也還行吧,路徑xxl-sso-server中src/main/resources下templates裡面的login.ftl和index.ftl
大家有問題可以評論區問我,有好的想法也可以評論區提出來,如果對您有用,幫忙點個贊,謝謝啦!