????????之前寫過一篇關(guān)于ruoyi cloud集成cas的但是使用的apereo的單點(diǎn)登錄,該應(yīng)用的文檔都是英文文檔,嘗試一下集成casdoor,其官方文檔比較詳細(xì)。
考慮到有些小伙伴上git不方便,需要用到的代碼和Windows工具,都在這了? ? ? ??
1、環(huán)境搭建
- Go 1.6+
- Node.js LTS (16或14)?這里我使用的是14.19.0,因?yàn)轫?xiàng)目使用的這個(gè)
- git
? ? 我沿用了之前的服務(wù)器,所以在官網(wǎng)下載Go 1.9的windows安裝包
? ? 下載msi,傻瓜式安裝,cmd輸入go version,出現(xiàn)版本號(hào),收工
? ? ?后兩項(xiàng)就不寫了,網(wǎng)上太多
2、casdoor部署
創(chuàng)建文件夾,右鍵git bash
?git clone https://github.com/casdoor/casdoor.git
下載完成代碼后,進(jìn)入casdoor-master文件夾,修改conf,修改app.conf文件,datasourcename:數(shù)據(jù)庫的用戶名,密碼,地址,dbName:數(shù)據(jù)庫名
appname = casdoor
httpport = 8000
runmode = dev
SessionOn = true
copyrequestbody = true
driverName = mysql
dataSourceName = root:123456@tcp(localhost:3306)/
dbName = casdoor
tableNamePrefix =
showSql = false
redisEndpoint =
defaultStorageProvider =
isCloudIntranet = false
authState = "casdoor"
socks5Proxy = "127.0.0.1:10808"
verificationCodeTimeout = 10
initScore = 2000
logPostOnly = true
origin = "https://door.casdoor.com"
staticBaseUrl = "https://cdn.casbin.org"
進(jìn)入cmd,切換國(guó)內(nèi)代理
go env -w GOPROXY=https://goproxy.cn
使用命令運(yùn)行后端
go run main.go
進(jìn)入web文件夾,cmd,下載yarn
npm install --global yarn
驗(yàn)證yarn是否安裝完成
yarn --version
安裝前端依賴
yarn install
前端運(yùn)行
yarn start
3配置casdoor
1、新建組織,將密碼類型呢改成bcrypt,并開啟軟刪除
2、新建同步器,配置數(shù)據(jù)庫密碼,修改表列?
3、保存和同步,查看若依的用戶是否存在
4、新建應(yīng)用和證書,在新建的應(yīng)用中,選擇新創(chuàng)建的證書,在重定向urls內(nèi)添加
http://localhost:81/login
4修改若依前端
1、安裝vue-sdk
npm i casdoor-vue-sdk --save
2、執(zhí)行指令
npx vue-demi-fix
3、修改main.js
//新增
import Casdoor from 'casdoor-vue-sdk'
import VueCompositionAPI from '@vue/composition-api'
const config = {
serverUrl: "你的casdoor路徑",
clientId: "客戶端id",
organizationName: "組織名稱",
appName: "應(yīng)用名稱",
redirectPath: "/login(重定向回來的路徑)",
};
Vue.use(VueCompositionAPI)
Vue.use(Casdoor,config)
//修改
new Vue({
el: '#app',
router,
store,
render: h => h(App)
}).$mount('#app')
4、修改login.vue(直接替換)
<template>
<div class="login">
<el-form ref="loginForm" class="login-form">
<h3 class="title">若依后臺(tái)管理系統(tǒng)</h3>
</el-form>
<!-- 底部 -->
<div class="el-login-footer">
<span>Copyright ? 2018-2022 ruoyi.vip All Rights Reserved.</span>
</div>
</div>
</template>
<script>
import { getCodeImg } from "@/api/login";
import Cookies from "js-cookie";
import { encrypt, decrypt } from '@/utils/jsencrypt'
export default {
name: "Login",
data() {
return {
codeUrl: "",
loginForm: {
code: "",
state: ""
},
loading: false,
// 驗(yàn)證碼開關(guān)
captchaEnabled: false,
// 注冊(cè)開關(guān)
register: true,
redirect: undefined
};
},
watch: {
$route: {
handler: function(route) {
this.redirect = route.query && route.query.redirect;
},
immediate: true
}
},
created() {
/*this.getCode();
this.getCookie();*/
let url = window.document.location.href//get url
let u = new URL(url);
this.loginForm.code = u.searchParams.get('code')//get code and state
this.loginForm.state = u.searchParams.get('state')
if(this.loginForm.code!=null&&this.loginForm.state!=null){//if code and state is null, execute handleLogin
this.handleLogin()
}else{
window.location.href = this.getSigninUrl();
}
},
methods: {
handleLogin() {
console.log("進(jìn)入handleLogin",this.loginForm);
this.$store.dispatch("Login",this.loginForm).then(()=>{
this.$router.push({path:this.redirect || "/"}).catch(()=>{});
}).catch(()=>{
this.loading = false;
})
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss">
.login {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
background-image: url("../assets/images/login-background.jpg");
background-size: cover;
}
.title {
margin: 0px auto 30px auto;
text-align: center;
color: #707070;
}
.login-form {
border-radius: 6px;
background: #ffffff;
width: 400px;
padding: 25px 25px 5px 25px;
.el-input {
height: 38px;
input {
height: 38px;
}
}
.input-icon {
height: 39px;
width: 14px;
margin-left: 2px;
}
}
.login-tip {
font-size: 13px;
text-align: center;
color: #bfbfbf;
}
.login-code {
width: 33%;
height: 38px;
float: right;
img {
cursor: pointer;
vertical-align: middle;
}
}
.el-login-footer {
height: 40px;
line-height: 40px;
position: fixed;
bottom: 0;
width: 100%;
text-align: center;
color: #fff;
font-family: Arial;
font-size: 12px;
letter-spacing: 1px;
}
.login-code-img {
height: 38px;
}
</style>
5、修改user.js的login方法
Login({ commit }, userInfo) {
const code = userInfo.code
const state = userInfo.state
return new Promise((resolve, reject) => {
login(code, state).then(res => {
let data = res.data
setToken(data.access_token)
commit('SET_TOKEN', data.access_token)
setExpiresIn(data.expires_in)
commit('SET_EXPIRES_IN', data.expires_in)
resolve()
}).catch(error => {
reject(error)
})
})
},
6、修改api下面的login.js
export function login(code,state) {
return request({
url: '/auth/login',
headers: {
isToken: false
},
method: 'post',
data: { code,state }
})
}
可以嘗試運(yùn)行,是否會(huì)跳轉(zhuǎn),是否能返回code和state
5、修改若依后端
1、導(dǎo)入依賴
<dependency>
<groupId>org.casbin</groupId>
<artifactId>casdoor-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>
2、新建實(shí)體CodeBody
package com.ruoyi.auth.form;
public class CodeBody {
private String code;
private String state;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
@Override
public String toString() {
return "CodeBody{" +
"code='" + code + '\'' +
", state='" + state + '\'' +
'}';
}
}
3、修改tokenController,login方法
@PostMapping("login")
public R<?> callback(@RequestBody CodeBody code) {//we should define a CodeBody entity which have code and state
String token = casdoorAuthService.getOAuthToken(code.getCode(), code.getState());
CasdoorUser casdoorUser = casdoorAuthService.parseJwtToken(token);
if(casdoorUser.getName()!=null){
String casdoorUserName = casdoorUser.getName();
if(sysLoginService.getUserByCasdoorName(casdoorUserName)==null){//if database haven't this user
// add this user into database
sysLoginService.casdoorRegister(casdoorUserName);
}
}
LoginUser userInfo = sysLoginService.casdoorLogin(casdoorUser.getName());//get this user's information by database
return R.ok(tokenService.createToken(userInfo));
}
4、sysloginService新增三個(gè)方法文章來源:http://www.zghlxwxcb.cn/news/detail-464724.html
public LoginUser casdoorLogin(String username){
// execute user
R<LoginUser> userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER);
if (R.FAIL == userResult.getCode())
{
throw new ServiceException(userResult.getMsg());
}
if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData()))
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "this user is not exist");
throw new ServiceException("user:" + username + " is not exist");
}
LoginUser userInfo = userResult.getData();
SysUser user = userResult.getData().getSysUser();
if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "sorry, your account was deleted");
throw new ServiceException("sorry, your account:" + username + " was deleted");
}
if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "your account is disabled, you can contact admin ");
throw new ServiceException("sorry, your account:" + username + " is disabled");
}
recordLogService.recordLogininfor(username, Constants.LOGIN_SUCCESS, "login successfully");
return userInfo;
}
public String getUserByCasdoorName(String casdoorUsername){
R<LoginUser> userResult = remoteUserService.getUserInfo(casdoorUsername, SecurityConstants.INNER);
if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData()))
{
//if this user is not in RuoYi-Cloud database and casdoor have this user, we should create this user in database
return null;
}
String username = userResult.getData().getSysUser().getUserName();
return username;
}
public void casdoorRegister(String username){
if (StringUtils.isAnyBlank(username))
{
throw new ServiceException("User must fill in");
}
SysUser sysUser = new SysUser();
sysUser.setUserName(username);
sysUser.setNickName(username);
R<?> registerResult = remoteUserService.registerUserInfo(sysUser, SecurityConstants.INNER);
System.out.println(registerResult);
if (R.FAIL == registerResult.getCode())
{
throw new ServiceException(registerResult.getMsg());
}
recordLogService.recordLogininfor(username, Constants.REGISTER, "register successfully");
}
5、bootstrap.yml內(nèi)新增casdoor配置文章來源地址http://www.zghlxwxcb.cn/news/detail-464724.html
server:
port: 36000
casdoor:
endpoint: casdoor地址
client-id: 客戶端id
client-secret: 客戶端密鑰
certificate: 證書名稱
jwtPublicKey: 證書公鑰,注意拷下來的公鑰,每一行結(jié)尾加\n\,如"-----BEGIN CERTIFICATE-----\n\
MIIE2TCCAsGgAwIBAgIDAeJAMA0GCSqGSIb3DQEBCwUAMCYxDjAMBgNVBAoTBWFk\n\
.
.
.
teANTdYzr6IIZiweG1/vvAXIk4HfjyVtOvxYAa6tfe0hpXDhCcqsO2ekpm0H\n\
-----END CERTIFICATE-----"
organization-name: 組織名稱
application-name: 應(yīng)用名稱
到了這里,關(guān)于ruoyi cloud集成casdoor的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!