Casdoor SDK

简介

与标准的 OIDC 协议相比,Casdoor 在 SDK 中提供了更多的功能,如用户管理、资源上传等。 通过 Casdoor SDK 连接到Casdoor 的成本比使用 OIDC 标准客户端库更高,并将提供灵活性最佳和最强大的 API。

Casdoor SDK可分为两类:

  1. 前端 SDK︰ Javascript SDK for websites, Android 或 iOS SDK for App。 Casdoor支持为网站和移动应用程序提供身份验证。
  2. 后端 SDK: Go, Java, Node.js, Python, PHP 等后端语言的 SDK 。
如果您的网站是以前端和后端分隔的方式开发的, 您可以使用 Javascript SDK: casdoor-js-sdk, 在前端直接集成casdoor。 如果您的网页应用程序是由 JSP 或 PHP 开发的传统网站,那您就只能使用后端SDK。 :::
Casdoor前端 SDK描述源代码
Javascript SDK适用于网页https://github.com/casdoor/casdoor-js-sdk
Android SDK适用于 Android 应用程序https://github.com/casdoor/casdoor-android-sdk
iOS SDK适用于 iOS 应用程序https://github.com/casdoor/casdoor-ios-sdk

接下来,根据您后端的语言,可以选择使用下面的后端SDK之一:

后端 SDK源代码
Go SDKhttps://github.com/casdoor/casdo-go-sdk
Java SDKhttps://github.com/casdoor/casdoor-java-sdk
Node.js SDKhttps://github.com/casdoor/casdoor-nodejs-sdk
Python SDKhttps://github.com/casdoor/casdoor-python-sdk
PHP SDKhttps://github.com/casdoor/casdoor-php-sdk
.NET SDKhttps://github.com/casdoor/casdonet-sdk

官方的 Casdoor SDK 完整列表请查看:https://github.com/casdoor?q=sdk&type=all&language=&sort=

如何使用 Casdoor SDK ?

1. 后端 SDK 配置

当您的应用程序启动时,您需要调用 InitConfig() 函数来初始化Casdoor SDK 配置。 例举Casdoor-go-sdk 为示例:https://github.com/casbin/casnode/blob/6d4c55f5c9a3c4bd8c85f2493abad3553b9c7ac0/controllers/account.go#L51-L64

  1. var CasdoorEndpoint = "https://door.casbin.com"
  2. var ClientId = "541738959670d221d59d"
  3. var ClientSecret = "66863369a64a5863827cf949bab70ed560ba24bf"
  4. var CasdoorOrganization = "casbin"
  5. var CasdoorApplication = "app-casnode"
  6. //go:embed token_jwt_key.pem
  7. var JwtPublicKey string
  8. func init() {
  9. auth.InitConfig(CasdoorEndpoint, ClientId, ClientSecret, JwtPublicKey, CasdoorOrganization, CasdoorApplication)
  10. }

InitConfig() 的所有参数被解释为:

参数是否必须描述
endpointCasdoor 的服务URL,例如: https://door.casbin.com or http://localhost:8000
clientId确定Casdoor 应用程序的客户端 ID
clientSecret确定Casdoor 应用程序的客户端密钥
jwtPublicKey确定Casdoor 应用程序证书的公钥
organizationName确定Casdoor 组织的名称
applicationNameCasdoor 应用程序的名称

2. 前端配置

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

  1. npm install casdoor-js-sdk

或者:

  1. yarn add casdoor-js-sdk

然后定义以下实用功能(在全局JS文件中更好,比如 Setting.js):

  1. import Sdk from "casdoor-js-sdk";
  2. export function initCasdoorSdk(config) {
  3. CasdoorSdk = new Sdk(config);
  4. }
  5. export function getSignupUrl() {
  6. return CasdoorSdk.getSignupUrl();
  7. }
  8. export function getSigninUrl() {
  9. return CasdoorSdk.getSigninUrl();
  10. }
  11. export function getUserProfileUrl(userName, account) {
  12. return CasdoorSdk.getUserProfileUrl(userName, account);
  13. }
  14. export function getMyProfileUrl(account) {
  15. return CasdoorSdk.getMyProfileUrl(account);
  16. }
  17. export function getMyResourcesUrl(account) {
  18. return CasdoorSdk.getMyProfileUrl(account).replace("/account?", "/resources?");
  19. }
  20. export function signin() {
  21. return CasdoorSdk.signin(ServerUrl);
  22. }

在您的前端代码的入口文件 (如 index.jsapp)。 s 在React中, 您需要通过调用 InitConfig() 函数来初始化 casdoor-js-sdk 前4个参数应该使用与 Casdoor 后端SDK 相同的值。 最后一个参数 redirectPath是重定向URL的相对路径,从Casdoor的登录页面返回。

  1. const config = {
  2. serverUrl: "https://door.casbin.com",
  3. clientId: "014ae4bd048734ca2dea",
  4. organizationName: "casbin",
  5. appName: "app-casnode",
  6. redirectPath: "/callback",
  7. };
  8. xxx.initCasdoorSdk(config);

(Optional) 因为我们使用的是React作为例子,所以我们的 /callback 路径击中了React路由,我们使用下面的React组件来接收 /callback 调用并发送到后端。 如果您直接重定向到后端(如JSP 或 PHP),您可以忽略此步骤。

  1. import React from "react";
  2. import { Button, Result, Spin } from "antd";
  3. import { withRouter } from "react-router-dom";
  4. import * as Setting from "./Setting";
  5. class AuthCallback extends React.Component {
  6. constructor(props) {
  7. super(props);
  8. this.state = {
  9. classes: props,
  10. msg: null,
  11. };
  12. }
  13. componentWillMount() {
  14. this.login();
  15. }
  16. login() {
  17. Setting.signin().then((res) => {
  18. if (res.status === "ok") {
  19. Setting.showMessage("success", `Logged in successfully`);
  20. Setting.goToLink("/");
  21. } else {
  22. this.setState({
  23. msg: res.msg,
  24. });
  25. }
  26. });
  27. }
  28. render() {
  29. return (
  30. <div style={{ textAlign: "center" }}>
  31. {this.state.msg === null ? (
  32. <Spin
  33. size="large"
  34. tip="Signing in..."
  35. style={{ paddingTop: "10%" }}
  36. />
  37. ) : (
  38. <div style={{ display: "inline" }}>
  39. <Result
  40. status="error"
  41. title="Login Error"
  42. subTitle={this.state.msg}
  43. extra={[
  44. <Button type="primary" key="details">
  45. Details
  46. </Button>,
  47. <Button key="help">Help</Button>,
  48. ]}
  49. />
  50. </div>
  51. )}
  52. </div>
  53. );
  54. }
  55. }
  56. export default withRouter(AuthCallback);

3. 获取登录 URL

接下来,您可以显示“注册”和“登录”按钮或链接到您的用户。 可以在前端或后端检索URL。 详细信息见: /docs/basic/core-concepts#login-urls

4. 获取并验证访问令牌

步骤如下:

  1. 用户点击登录URL并重定向到Casdoor的登录页面,如 https://door.casbin。 om/login/oauth/authorize?client_id=014ae4bd048734ca2dea&response_type=code&redirect_uri=https%3A%2F%2Fforum.casbin.com%2F回调&scope=read&state=app-casnode
  2. 用户输入用户名 & 密码并点击 登录 (或点击第三方登录按钮,如 使用 GitHub 登录)。
  3. 该用户被重定向到您的应用,使用Casto发行的授权码(例如: https://forum.casbin)。 om?code=xxx&state=yyy), 您的应用程序的后端需要将授权码与访问令牌交换,并验证访问令牌是否有效和由Casdoor签发。 函数 GetOAuthToken() and ParseJwtToken() 由 Casdoor 后端SDK 提供。

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

  1. // get code and state from the GET parameters of the redirected URL
  2. code := c.Input().Get("code")
  3. state := c.Input().Get("state")
  4. // exchange the access token with code and state
  5. token, err := auth.GetOAuthToken(code, state)
  6. if err != nil {
  7. panic(err)
  8. }
  9. // verify the access token
  10. claims, err := auth.ParseJwtToken(token.AccessToken)
  11. if err != nil {
  12. panic(err)
  13. }

如果 ParseJwtToken() 结束时没有错误,那么用户已成功登录到应用程序。 返回的 认领 可以稍后用来识别用户。

4. 用访问令牌识别用户

::info 这个部分实际上是您的应用程序自己的业务逻辑,而不是OIDC, OAuth 或 Cassdoor的一部分。 我们只是提供良好做法,因为许多人不知道下一步怎么办。 :::

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

ParseJwtToken() 返回的变量 claims 被定义为:

  1. Type Claims struct
  2. User
  3. AccessToken string `json:"accessToken"
  4. jwt.RegisteredClaims
  5. }
  1. User: the User object, containing all information for the logged-in user, see definition at: /docs/basic/core-concepts#user
  2. AccessToken: 访问令牌字符串。
  3. jwt.RegisteredClaim: JWT需要一些其他值。

此时此刻,应用程序通常有两种方法记住用户会话: session and JWT

会议

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

  1. token, err := auth.GetOAuthToken(dode, state)
  2. if err != nil }
  3. panic(err)
  4. }
  5. claim, err := auth.ParseJwtToken(token) ccccessToken)
  6. 如果err != nil 然后
  7. panic(err)
  8. }
  9. claims.AccessToken = token.AccessToken
  10. c.SetSessionUser(claims) // 设置会话

JWT

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

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

5. (可选) 与用户表的互动

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

  • GetUser(name string): 通过用户名获取用户。
  • GetUsers(): 获取所有用户。
  • AddUser(): 添加一个用户。
  • UpdateUser(): 更新一个用户。
  • DeleteUser(): 删除一个用户。
  • CheckUserPassword(auth.User): 检查用户的密码。

这些函数是通过对 Castor Public API 进行RESTful 通话实现的。 如果在 Casdoor 后端SDK 中没有提供函数,您可以自己进行RESTFify的呼叫。