之前写过一篇关于ruoyi cloud集成cas的但是使用的apereo的单点登录,该应用的文档都是英文文档,尝试一下集成casdoor,其官方文档比较详细。
考虑到有些小伙伴上git不方便,需要用到的代码和Windows工具,都在这了
1、环境搭建
- Go 1.6+
- Node.js LTS (16或14) 这里我使用的是14.19.0,因为项目使用的这个
- git
我沿用了之前的服务器,所以在官网下载Go 1.9的windows安装包
下载msi,傻瓜式安装,cmd输入go version,出现版本号,收工
后两项就不写了,网上太多
2、casdoor部署
创建文件夹,右键git bash
git clone https://github.com/casdoor/casdoor.git
下载完成代码后,进入casdoor-master文件夹,修改conf,修改app.conf文件,datasourcename:数据库的用户名,密码,地址,dbName:数据库名
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"
进入cmd,切换国内代理
go env -w GOPROXY=https://goproxy.cn
使用命令运行后端
go run main.go
进入web文件夹,cmd,下载yarn
npm install --global yarn
验证yarn是否安装完成
yarn --version
安装前端依赖
yarn install
前端运行
yarn start
3配置casdoor
1、新建组织,将密码类型呢改成bcrypt,并开启软删除
2、新建同步器,配置数据库密码,修改表列
3、保存和同步,查看若依的用户是否存在
4、新建应用和证书,在新建的应用中,选择新创建的证书,在重定向urls内添加
http://localhost:81/login
4修改若依前端
1、安装vue-sdk
npm i casdoor-vue-sdk --save
2、执行指令
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: "应用名称",
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">若依后台管理系统</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,
// 验证码开关
captchaEnabled: false,
// 注册开关
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("进入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 }
})
}
可以尝试运行,是否会跳转,是否能返回code和state
5、修改若依后端
1、导入依赖
<dependency>
<groupId>org.casbin</groupId>
<artifactId>casdoor-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>
2、新建实体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新增三个方法文章来源:https://www.toymoban.com/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内新增casdoor配置文章来源地址https://www.toymoban.com/news/detail-464724.html
server:
port: 36000
casdoor:
endpoint: casdoor地址
client-id: 客户端id
client-secret: 客户端密钥
certificate: 证书名称
jwtPublicKey: 证书公钥,注意拷下来的公钥,每一行结尾加\n\,如"-----BEGIN CERTIFICATE-----\n\
MIIE2TCCAsGgAwIBAgIDAeJAMA0GCSqGSIb3DQEBCwUAMCYxDjAMBgNVBAoTBWFk\n\
.
.
.
teANTdYzr6IIZiweG1/vvAXIk4HfjyVtOvxYAa6tfe0hpXDhCcqsO2ekpm0H\n\
-----END CERTIFICATE-----"
organization-name: 组织名称
application-name: 应用名称
到了这里,关于ruoyi cloud集成casdoor的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!