Refactor the auth code.

This commit is contained in:
Yang Luo
2021-02-14 16:59:08 +08:00
parent 9b45e5fe43
commit b5b86262d6
9 changed files with 117 additions and 102 deletions

View File

@ -27,12 +27,12 @@ import ProviderEditPage from "./ProviderEditPage";
import ApplicationListPage from "./ApplicationListPage"; import ApplicationListPage from "./ApplicationListPage";
import ApplicationEditPage from "./ApplicationEditPage"; import ApplicationEditPage from "./ApplicationEditPage";
import AccountPage from "./account/AccountPage"; import AccountPage from "./account/AccountPage";
import LoginPage from "./account/LoginPage";
import HomePage from "./basic/HomePage"; import HomePage from "./basic/HomePage";
import CustomGithubCorner from "./CustomGithubCorner"; import CustomGithubCorner from "./CustomGithubCorner";
import * as Auth from "./auth/Auth";
import Face from "./auth/Face"; import Face from "./auth/Face";
import * as Auth from "./auth/AuthBackend"; import LoginPage from "./auth/LoginPage";
import * as AuthBackend from "./auth/AuthBackend"; import * as AuthBackend from "./auth/AuthBackend";
import AuthCallback from "./auth/AuthCallback"; import AuthCallback from "./auth/AuthCallback";
@ -48,7 +48,10 @@ class App extends Component {
}; };
Setting.initServerUrl(); Setting.initServerUrl();
Auth.setAuthServerUrl(Setting.ServerUrl); Auth.initAuthWithConfig({
serverUrl: Setting.ServerUrl,
appName: "app-built-in",
});
} }
componentWillMount() { componentWillMount() {
@ -78,12 +81,6 @@ class App extends Component {
this.getAccount(); this.getAccount();
} }
onUpdateAccount(account) {
this.setState({
account: account
});
}
getAccount() { getAccount() {
AuthBackend.getAccount() AuthBackend.getAccount()
.then((res) => { .then((res) => {

View File

@ -18,7 +18,7 @@ import {Button, Col, Popconfirm, Row, Table} from 'antd';
import moment from "moment"; import moment from "moment";
import * as Setting from "./Setting"; import * as Setting from "./Setting";
import * as ProviderBackend from "./backend/ProviderBackend"; import * as ProviderBackend from "./backend/ProviderBackend";
import * as Auth from "./auth/Auth"; import * as Provider from "./auth/Provider";
class ProviderListPage extends React.Component { class ProviderListPage extends React.Component {
constructor(props) { constructor(props) {
@ -125,7 +125,7 @@ class ProviderListPage extends React.Component {
sorter: (a, b) => a.type.localeCompare(b.type), sorter: (a, b) => a.type.localeCompare(b.type),
render: (text, record, index) => { render: (text, record, index) => {
return ( return (
<img width={30} height={30} src={Auth.getAuthLogo(record)} alt={record.displayName} /> <img width={30} height={30} src={Provider.getAuthLogo(record)} alt={record.displayName} />
) )
} }
}, },

View File

@ -12,51 +12,11 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
const AuthState = "casdoor"; export let authConfig = {
serverUrl: "http://example.com", // your Casdoor URL, like the official one: https://door.casbin.com
const GoogleAuthScope = "profile+email" appName: "app-example", // your Casdoor application name, like: "app-built-in"
const GoogleAuthUri = "https://accounts.google.com/signin/oauth";
const GoogleAuthLogo = "https://cdn.jsdelivr.net/gh/casbin/static/img/social_google.png";
const GithubAuthScope = "user:email+read:user"
const GithubAuthUri = "https://github.com/login/oauth/authorize";
const GithubAuthLogo = "https://cdn.jsdelivr.net/gh/casbin/static/img/social_github.png";
const QqAuthScope = "get_user_info"
const QqAuthUri = "https://graph.qq.com/oauth2.0/authorize";
const QqAuthLogo = "https://cdn.jsdelivr.net/gh/casbin/static/img/social_qq.png";
const WeChatAuthScope = "snsapi_login"
const WeChatAuthUri = "https://open.weixin.qq.com/connect/qrconnect";
const WeChatAuthLogo = "https://cdn.jsdelivr.net/gh/casbin/static/img/social_wechat.png";
export function getAuthLogo(provider) {
if (provider.type === "google") {
return GoogleAuthLogo;
} else if (provider.type === "github") {
return GithubAuthLogo;
} else if (provider.type === "qq") {
return QqAuthLogo;
} else if (provider.type === "wechat") {
return WeChatAuthLogo;
}
} }
export function getClientUrl() { export function initAuthWithConfig(config) {
const hostname = window.location.hostname; authConfig = config;
if (hostname === "localhost") {
return `http://${hostname}:7001`;
} else {
return `https://${hostname}`;
}
}
export function getAuthUrl(provider, method) {
const redirectUri = `${getClientUrl()}/callback/${provider.type}/${provider.name}/${method}`;
if (provider.type === "google") {
return `${GoogleAuthUri}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&scope=${GoogleAuthScope}&response_type=code&state=${AuthState}`;
} else if (provider.type === "github") {
return `${GithubAuthUri}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&scope=${GithubAuthScope}&response_type=code&state=${AuthState}`;
} else if (provider.type === "qq") {
return `${QqAuthUri}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&scope=${QqAuthScope}&response_type=code&state=${AuthState}`;
} else if (provider.type === "wechat") {
return `${WeChatAuthUri}?appid=${provider.clientId}&redirect_uri=${redirectUri}&scope=${WeChatAuthScope}&response_type=code&state=${AuthState}#wechat_redirect`;
}
} }

View File

@ -12,21 +12,17 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
let ServerUrl = "https://door.casbin.com"; import {authConfig} from "./Auth";
export function setAuthServerUrl(serverUrl) {
ServerUrl = serverUrl;
}
export function getAccount() { export function getAccount() {
return fetch(`${ServerUrl}/api/get-account`, { return fetch(`${authConfig.serverUrl}/api/get-account`, {
method: 'GET', method: 'GET',
credentials: 'include' credentials: 'include'
}).then(res => res.json()); }).then(res => res.json());
} }
export function register(values) { export function register(values) {
return fetch(`${ServerUrl}/api/register`, { return fetch(`${authConfig.serverUrl}/api/register`, {
method: 'POST', method: 'POST',
credentials: "include", credentials: "include",
body: JSON.stringify(values), body: JSON.stringify(values),
@ -34,7 +30,7 @@ export function register(values) {
} }
export function login(values) { export function login(values) {
return fetch(`${ServerUrl}/api/login`, { return fetch(`${authConfig.serverUrl}/api/login`, {
method: 'POST', method: 'POST',
credentials: "include", credentials: "include",
body: JSON.stringify(values), body: JSON.stringify(values),
@ -42,15 +38,22 @@ export function login(values) {
} }
export function logout() { export function logout() {
return fetch(`${ServerUrl}/api/logout`, { return fetch(`${authConfig.serverUrl}/api/logout`, {
method: 'POST', method: 'POST',
credentials: "include", credentials: "include",
}).then(res => res.json()); }).then(res => res.json());
} }
export function authLogin(providerName, code, state, redirectUrl, method) { export function authLogin(providerName, code, state, redirectUrl, method) {
return fetch(`${ServerUrl}/api/auth/login?provider=${providerName}&code=${code}&state=${state}&redirect_url=${redirectUrl}&method=${method}`, { return fetch(`${authConfig.serverUrl}/api/auth/login?provider=${providerName}&code=${code}&state=${state}&redirect_url=${redirectUrl}&method=${method}`, {
method: 'GET', method: 'GET',
credentials: 'include', credentials: 'include',
}).then(res => res.json()); }).then(res => res.json());
} }
export function getApplication(owner, name) {
return fetch(`${authConfig.serverUrl}/api/get-application?id=${owner}/${encodeURIComponent(name)}`, {
method: "GET",
credentials: "include"
}).then(res => res.json());
}

View File

@ -16,7 +16,6 @@ import React from "react";
import {message, Spin} from "antd"; import {message, Spin} from "antd";
import {withRouter} from "react-router-dom"; import {withRouter} from "react-router-dom";
import * as AuthBackend from "./AuthBackend"; import * as AuthBackend from "./AuthBackend";
import {getClientUrl} from "./Auth";
class AuthCallback extends React.Component { class AuthCallback extends React.Component {
constructor(props) { constructor(props) {
@ -49,7 +48,7 @@ class AuthCallback extends React.Component {
authLogin() { authLogin() {
let redirectUrl; let redirectUrl;
redirectUrl = `${getClientUrl()}/callback/${this.state.providerType}/${this.state.providerName}/${this.state.method}`; redirectUrl = `${window.location.origin}/callback/${this.state.providerType}/${this.state.providerName}/${this.state.method}`;
AuthBackend.authLogin(this.state.providerName, this.state.code, this.state.state, redirectUrl, this.state.method) AuthBackend.authLogin(this.state.providerName, this.state.code, this.state.state, redirectUrl, this.state.method)
.then((res) => { .then((res) => {
if (res.status === "ok") { if (res.status === "ok") {

View File

@ -15,9 +15,8 @@
import React from "react"; import React from "react";
import {Button, Checkbox, Col, Form, Input, Row} from "antd"; import {Button, Checkbox, Col, Form, Input, Row} from "antd";
import {LockOutlined, UserOutlined} from "@ant-design/icons"; import {LockOutlined, UserOutlined} from "@ant-design/icons";
import * as ApplicationBackend from "../backend/ApplicationBackend";
import * as AuthBackend from "./AuthBackend"; import * as AuthBackend from "./AuthBackend";
import * as Auth from "./Auth"; import * as Provider from "./Provider";
import * as Util from "./Util"; import * as Util from "./Util";
class Face extends React.Component { class Face extends React.Component {
@ -39,7 +38,7 @@ class Face extends React.Component {
return; return;
} }
ApplicationBackend.getApplication("admin", this.state.applicationName) AuthBackend.getApplication("admin", this.state.applicationName)
.then((application) => { .then((application) => {
this.setState({ this.setState({
application: application, application: application,
@ -129,8 +128,8 @@ class Face extends React.Component {
{ {
this.getApplicationObj().providerObjs.map(provider => { this.getApplicationObj().providerObjs.map(provider => {
return ( return (
<img width={30} height={30} src={Auth.getAuthLogo(provider)} alt={provider.displayName} style={{cursor: "pointer", margin: "3px"}} onClick={() => { <img width={30} height={30} src={Provider.getAuthLogo(provider)} alt={provider.displayName} style={{cursor: "pointer", margin: "3px"}} onClick={() => {
window.location.href = Auth.getAuthUrl(provider, "signup"); window.location.href = Provider.getAuthUrl(provider, "signup");
}} }}
/> />
); );

View File

@ -13,12 +13,13 @@
// limitations under the License. // limitations under the License.
import React from 'react'; import React from 'react';
import Face from "../auth/Face"; import Face from "./Face";
import {authConfig} from "./Auth";
class LoginPage extends React.Component { class LoginPage extends React.Component {
render() { render() {
return ( return (
<Face applicationName={"app-built-in"} account={this.props.account} onLoggedIn={this.props.onLoggedIn.bind(this)} {...this.props} /> <Face applicationName={authConfig.appName} account={this.props.account} onLoggedIn={this.props.onLoggedIn.bind(this)} {...this.props} />
) )
} }
} }

56
web/src/auth/Provider.js Normal file
View File

@ -0,0 +1,56 @@
// Copyright 2021 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
const AuthState = "casdoor";
const GoogleAuthScope = "profile+email"
const GoogleAuthUri = "https://accounts.google.com/signin/oauth";
const GoogleAuthLogo = "https://cdn.jsdelivr.net/gh/casbin/static/img/social_google.png";
const GithubAuthScope = "user:email+read:user"
const GithubAuthUri = "https://github.com/login/oauth/authorize";
const GithubAuthLogo = "https://cdn.jsdelivr.net/gh/casbin/static/img/social_github.png";
const QqAuthScope = "get_user_info"
const QqAuthUri = "https://graph.qq.com/oauth2.0/authorize";
const QqAuthLogo = "https://cdn.jsdelivr.net/gh/casbin/static/img/social_qq.png";
const WeChatAuthScope = "snsapi_login"
const WeChatAuthUri = "https://open.weixin.qq.com/connect/qrconnect";
const WeChatAuthLogo = "https://cdn.jsdelivr.net/gh/casbin/static/img/social_wechat.png";
export function getAuthLogo(provider) {
if (provider.type === "google") {
return GoogleAuthLogo;
} else if (provider.type === "github") {
return GithubAuthLogo;
} else if (provider.type === "qq") {
return QqAuthLogo;
} else if (provider.type === "wechat") {
return WeChatAuthLogo;
}
}
export function getAuthUrl(provider, method) {
const redirectUri = `${window.location.origin}/callback/${provider.type}/${provider.name}/${method}`;
if (provider.type === "google") {
return `${GoogleAuthUri}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&scope=${GoogleAuthScope}&response_type=code&state=${AuthState}`;
} else if (provider.type === "github") {
return `${GithubAuthUri}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&scope=${GithubAuthScope}&response_type=code&state=${AuthState}`;
} else if (provider.type === "qq") {
return `${QqAuthUri}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&scope=${QqAuthScope}&response_type=code&state=${AuthState}`;
} else if (provider.type === "wechat") {
return `${WeChatAuthUri}?appid=${provider.clientId}&redirect_uri=${redirectUri}&scope=${WeChatAuthScope}&response_type=code&state=${AuthState}#wechat_redirect`;
}
}