跳到主内容

Casdoor SDKs

概述​

Casdoor SDKs在标准OIDC基础上扩展了用户管理、资源上传及其他功能。它们的设置比通用的OIDC客户端稍多一些,但能为您提供完整的Casdoor API。

前端 SDK:用于网页(JavaScript、React、Vue 等)和移动端(Android、iOS、React Native、Flutter)。
后端 SDK:用于 Go、Java、Node.js、Python、PHP、.NET、Rust、C++ 等。

提示

前后端分离时,界面里用前端 SDK(例如 casdoor-js-sdk、casdoor-react-sdk、casdoor-vue-sdk),后端用后端 SDK 校验令牌和调用 API。对于传统的服务器端渲染应用(JSP、PHP),后端SDK可能就足够了。示例:casdoor-python-vue-sdk-example。

移动SDK映射的工具SDK 代码示例代码
Android SDK适用于Android应用casdoor-android-sdkcasdoor-android-example
iOS SDK针对iOS应用程序casdoor-ios-sdkcasdoor-ios-example
React Native SDK对于React Native应用程序casdoor-react-native-sdkcasdoor-react-native-example
Flutter SDK适用于Flutter应用casdoor-flutter-sdkcasdoor-flutter-example
Firebase SDK适用于 Google Firebase 应用casdoor-firebase-example
Unity游戏SDK适用于Unity 2D/3D PC/移动游戏casdoor-dotnet-sdkcasdoor-unity-example
uni-app SDK对于uni-app应用程序casdoor-uniapp-sdkcasdoor-uniapp-example
提示

Mobile apps that sign users in natively instead of in a browser can use the Verification Code grant for SMS or email sign-in with automatic signup, and let signed-in users approve the QR code on your website's login page.

桌面版SDK描述SDK 代码示例代码
Electron SDK对于Electron应用casdoor-js-sdkcasdoor-electron-example
.NET 桌面 SDK适用于 .NET 桌面应用casdoor-dotnet-sdkWPF:casdoor-dotnet-desktop-example
WinForms:casdoor-dotnet-winform-example
Avalonia UI:casdoor-dotnet-avalonia-example
C/C++ SDK用于C/C++桌面应用程序casdoor-cpp-sdkcasdoor-cpp-qt-example
Web前端SDK描述SDK 代码示例代码
Javascript SDK对于传统的非SPA网站casdoor-js-sdkNode.js 后端:casdoor-raw-js-example
Go 后端:casdoor-go-react-sdk-example
仅前端的SDK仅用于前端的SPA网站casdoor-js-sdkcasdoor-react-only-example
React SDK适用于React网站casdoor-react-sdkNode.js 后端:casdoor-nodejs-react-example
Java 后端:casdoor-spring-security-react-example
Next.js SDK针对Next.js网站nextjs-auth
Nuxt SDK对于Nuxt网站nuxt-auth
Vue SDK适用于Vue网站casdoor-vue-sdkcasdoor-python-vue-sdk-example
Angular SDK适用于Angular网站casdoor-angular-sdkcasdoor-nodejs-angular-example
Flutter SDK适用于Flutter Web网站casdoor-flutter-sdkcasdoor-flutter-example
ASP.NET SDK适用于ASP.NET Blazor WASM网站Blazor.BFF.OpenIDConnect.Templatecasdoor-dotnet-blazorwasm-oidc-example
Firebase SDK适用于 Google Firebase 应用casdoor-firebase-example

将前端与服务器语言的后端 SDK 配对:

Web后端SDK描述Sdk 代码示例代码
Go SDK对于Go后端casdoor-go-sdkcasdoor-go-react-sdk-example
Java SDK针对Java后端casdoor-java-sdkcasdoor-spring-boot-starter, casdoor-spring-boot-example, casdoor-spring-security-react-example, quarkus-casdoor-auth (Quarkus)
Node.js SDK针对Node.js后端casdoor-nodejs-sdkcasdoor-nodejs-react-example
Python SDK针对Python后端casdoor-python-sdkFlask:casdoor-python-vue-sdk-example
Django:casdoor-django-js-sdk-example
FastAPI:casdoor-fastapi-js-sdk-example
PHP SDK针对PHP后端casdoor-php-sdkwordpress-casdoor-plugin
.NET SDK针对ASP.NET后端casdoor-dotnet-sdkcasdoor-dotnet-sdk-example
Rust SDK针对Rust后端casdoor-rust-sdkcasdoor-rust-example
C/C++ SDK针对 C/C++ 后端casdoor-cpp-sdkcasdoor-cpp-qt-example
Dart SDK针对Dart后端casdoor-dart-sdk
Ruby SDK针对Ruby后端casdoor-ruby-sdk

全部官方 SDK: https://github.com/orgs/casdoor/repositories?q=sdk&type=all&language=&sort=。

使用SDK​

1. 后端 SDK 配置​

启动时,请使用您的Casdoor端点、客户端ID、客户端密钥,以及(用于JWT验证的)公钥调用SDK的初始化函数。 casdoor-go-sdk 示例:https://github.com/casbin/casnode/blob/6d4c55f5c9a3c4bd8c85f2493abad3553b9c7ac0/controllers/account.go#L51-L64

var CasdoorEndpoint = "https://door.casdoor.com"
var ClientId = "541738959670d221d59d"
var ClientSecret = "66863369a64a5863827cf949bab70ed560ba24bf"
var CasdoorOrganization = "casbin"
var CasdoorApplication = "app-casnode"

//go:embed token_jwt_key.pem
var JwtPublicKey string

func init() {
auth.InitConfig(CasdoorEndpoint, ClientId, ClientSecret, JwtPublicKey, CasdoorOrganization, CasdoorApplication)
}

InitConfig() 的各个参数说明如下:

参数必须描述
endpoint是Casdoor 服务器地址,例如 https://door.casdoor.com 或 http://localhost:8000
clientId是Casdoor应用的客户端ID
clientSecret是Casdoor应用程序的客户端密钥
jwtPublicKey是Casdoor应用程序的证书的公钥
organizationName是Casdoor组织的名称
应用程序名称不Casdoor应用程序的名称
提示

jwtPublicKey 可以在 Certs 页面管理,如下所示。

证书管理

从证书编辑页面复制或下载公钥,以供SDK使用。

证书编辑

然后在应用程序编辑页面选择该证书。

证书选择

. 前端配置​

首先,通过NPM或Yarn安装casdoor-js-sdk:

npm install casdoor-js-sdk

或者:

yarn add casdoor-js-sdk

然后定义以下工具函数(最好放在 Setting.js 这类全局 JS 文件中):

import Sdk from "casdoor-js-sdk";

export function initCasdoorSdk(config) {
CasdoorSdk = new Sdk(config);
}

export function getSignupUrl() {
return CasdoorSdk.getSignupUrl();
}

export function getSigninUrl() {
return CasdoorSdk.getSigninUrl();
}

export function getUserProfileUrl(userName, account) {
return CasdoorSdk.getUserProfileUrl(userName, account);
}

export function getMyProfileUrl(account) {
return CasdoorSdk.getMyProfileUrl(account);
}

export function getMyResourcesUrl(account) {
return CasdoorSdk.getMyProfileUrl(account).replace("/account?", "/resources?");
}

export function signin() {
return CasdoorSdk.signin(ServerUrl);
}

export function showMessage(type, text) {
if (type === "") {
return;
} else if (type === "success") {
message.success(text);
} else if (type === "error") {
message.error(text);
}
}

export function goToLink(link) {
window.location.href = link;
}

在前端入口文件(例如 React 中的 index.js 或 app.js)中,调用 InitConfig() 并传入所需参数来初始化 casdoor-js-sdk。前4个参数应该使用与 Casdoor 后端SDK 相同的值。最后一个参数 redirectPath 是从 Casdoor 登录页返回时跳转地址的相对路径。

const config = {
serverUrl: "https://door.casdoor.com",
clientId: "014ae4bd048734ca2dea",
organizationName: "casbin",
appName: "app-casnode",
redirectPath: "/callback",
};

xxx.initCasdoorSdk(config);

(可选) 本示例使用 React;/callback 路由由下面的组件处理,它把请求转发给后端。如果您的回调直接转到后端(例如JSP或PHP),请跳过此步骤。

import React from "react";
import {Button, Result, Spin} from "antd";
import {withRouter} from "react-router-dom";
import * as Setting from "./Setting";

class AuthCallback extends React.Component {
constructor(props) {
super(props);
this.state = {
classes: props,
msg: null,
};
}

componentWillMount() {
this.login();
}

login() {
Setting.signin().then((res) => {
if (res.status === "ok") {
Setting.showMessage("success", `Logged in successfully`);
Setting.goToLink("/");
} else {
this.setState({
msg: res.msg,
});
}
});
}

render() {
return (
<div style={{textAlign: "center"}}>
{this.state.msg === null ? (
<Spin
size="large"
tip="Signing in..."
style={{paddingTop: "10%"}}
/>
) : (
<div style={{display: "inline"}}>
<Result
status="error"
title="Login Error"
subTitle={this.state.msg}
extra={[
<Button type="primary" key="details">
Details
</Button>,
<Button key="help">Help</Button>,
]}
/>
</div>
)}
</div>
);
}
}

export default withRouter(AuthCallback);

3. 获取登录 URL​

向用户显示“注册”和“登录”按钮或链接;URL可从前端或后端获取。见 登录地址。

4. 获取并验证token​

步骤如下:

  1. 用户点击登录地址,跳转到 Casdoor 登录页, 例如:https://door.casdoor.com/login/oauth/authorize?client_id=014ae4bd048734ca2dea&response_type=code&redirect_uri=https%3A%2F%2Fforum.casbin.com%2Fcallback&scope=read&state=app-casnode
  2. 用户输入用户名和密码,点击 Sign In(或者直接点击第三方登录按钮, 例如 Sign in with GitHub)。
  3. 用户带着 Casdoor 签发的授权码跳回你的应用( 例如 https://forum.casbin.com?code=xxx&state=yyy),应用后端需要用授权码换取访问令牌,并校验该访问令牌有效且由 Casdoor 签发。 GetOAuthToken() 和 ParseJwtToken() 函数由 Casdoor 后端 SDK 提供。

以下代码显示如何获取并验证访问令牌。 Casnode(一个用 Go 编写的论坛网站)的真实示例见:https://github.com/casbin/casnode/blob/6d4c55f5c9a3c4bd8c85f2493abad3553b9c7ac0/controllers/account.go#L51-L64

// get code and state from the GET parameters of the redirected URL
code := c.Input().Get("code")
state := c.Input().Get("state")

// exchange the access token with code and state
token, err := auth.GetOAuthToken(code, state)
if err != nil {
panic(err)
}

// verify the access token
claims, err := auth.ParseJwtToken(token.AccessToken)
if err != nil {
panic(err)
}

如果 ParseJwtToken() 执行完没有报错,说明用户已经成功登录应用。返回的 claims 之后可以用来识别该用户。

4. 用token识别用户​

信息

这一部分实际上是您的应用程序本身的业务逻辑,而不是OIDC、OAuth 或Cassdoor的一部分。我们只是提供正确做法,因为许多人不知道该怎么做。

在Cassdoor中,访问令牌通常与ID令牌相同。他们是一样的。因此,访问令牌包含登录用户的所有信息。

ParseJwtToken() 返回的 claims 变量定义如下:

type Claims struct {
User
AccessToken string `json:"accessToken"`
jwt.RegisteredClaims
}
  1. User:User 对象,包含已登录用户的全部信息,定义 见:/docs/basic/core-concepts#user
  2. AccessToken:访问令牌字符串。
  3. jwt.RegisteredClaims:JWT 所需的其他字段。

此时,应用通常有两种方式记住用户会话:session 和 JWT。

Session​

设置Session的方法因语言和框架而大不相同。例如 Casnode 使用 Beego Web 框架,通过调用 c.SetSessionUser() 设置会话。

token, err := auth.GetOAuthToken(code, state)
if err != nil {
panic(err)
}

claims, err := auth.ParseJwtToken(token.AccessToken)
if err != nil {
panic(err)
}

claims.AccessToken = token.AccessToken
c.SetSessionUser(claims) // set session

JWT​

Casdoor 返回的 accessToken 实际上就是一个 JWT。因此,如果您的应用程序使用 JWT 来保持用户session,只需直接为它使用访问令牌:

  1. 将访问令牌发送到前端,在本地存储浏览器等地方保存。
  2. 让浏览器为每一个请求发送访问令牌到后端。
  3. 在后端调用 ParseJwtToken() 或你自己的函数校验访问令牌,获取已登录用户的信息。

5. (可选) 操作用户表​

信息

这部分由 Casdoor Public API 提供,不属于 OIDC 或 OAuth。

Casdoor Backend SDK 提供了许多辅助功能,不仅限于:

  • GetUser(name string):按用户名获取用户。
  • GetUsers():获取所有用户。
  • AddUser():添加用户。
  • UpdateUser():更新用户。
  • DeleteUser():删除用户。
  • CheckUserPassword(auth.User):校验用户密码。

这些函数通过调用 Casdoor Public API 的 RESTful 接口实现。如果 Casdoor 后端 SDK 中没有某个函数,直接调用 Public API。

6. (可选) 通过 SDK 管理应用​

Casdoor SDKs还提供以编程方式管理应用的功能:

  • AddApplication():创建新应用。
  • GetApplication(name string):按名称获取应用。
  • GetApplications():获取所有应用。
  • UpdateApplication():更新应用。
  • DeleteApplication():删除应用。

通过 SDK 的 AddApplication() 创建应用时,Casdoor 会自动用合理的默认值初始化必要字段。这包括注册项(ID、用户名、显示名称、密码、确认密码、电子邮件、电话、协议)、登录项以及登录方式。这可确保以编程方式创建的应用程序在UI中正常运行,而无需手动配置这些基本设置。