如何将 Auth0 与 react-admin 一起使用?
Posted
技术标签:
【中文标题】如何将 Auth0 与 react-admin 一起使用?【英文标题】:How to use Auth0 with react-admin? 【发布时间】:2020-04-22 17:54:34 【问题描述】:我正在尝试在 react-admin v3 应用程序中使用 Auth0 实现身份验证。我需要实现一个与 Auth0 对话的authProvider
。这听起来应该在某处可用,但我能找到的最接近的是 https://github.com/alexicum/merge-admin/blob/master/src/Auth/index.js,它大约有 2 年的历史(从那时起 SDK 发生了变化)。
是否有一个 Auth0 authProvider 我可以重用,还是我必须自己实现它?
谢谢!
【问题讨论】:
你有什么运气吗?我不是 React 开发人员,并且即将尝试同样的事情,我很惊讶你的问题是我能找到的最相关的事情。 @Hastarin 不是真的,我必须自己开发一个。它仍然很老套,并且 Auth0 和 react-admin AuthProvider 抽象在某些地方存在漏洞。它现在正在工作,但我仍在寻找更好的解决方案。迄今为止最好的是github.com/alexicum/merge-admin/blob/master/src/Auth/index.js。 【参考方案1】:为了参考,这里是一个将 react admin 与 auth0-react 包集成的示例
index.js
import Auth0Provider from "@auth0/auth0-react";
ReactDOM.render(
<Auth0Provider
domain="XXXXX.auth0.com"
clientId="XXXXX"
audience="https://XXXXX"
redirectUri=window.location.origin
>
<React.StrictMode>
<App />
</React.StrictMode>
</Auth0Provider>,
document.getElementById("root")
);
App.js
import withAuth0, withAuthenticationRequired from "@auth0/auth0-react";
import ApolloClient from "apollo-boost";
// I'm using Hasura w/ JWT Auth, so here's an example of how to set Authorization Header
async componentDidMount()
const token = await this.props.auth0.getAccessTokenSilently();
const client = new ApolloClient(
uri: "https://HASURA_URL/v1/graphql",
headers:
Authorization: `Bearer $token`
,
);
buildHasuraProvider( client ).then((dataProvider) =>
this.setState( dataProvider )
);
export default withAuthenticationRequired(withAuth0(App));
【讨论】:
虽然这不符合 react-admin 处理身份验证的自以为是的方式,但这当然非常简单,到目前为止看起来很可靠。谢谢!【参考方案2】:我已经使用 Auth0 和 react-admin 的身份验证方式创建了一个示例应用程序
https://github.com/spintech-software/react-admin-auth0-example
这是供参考的身份验证提供程序代码
import authConfig from "./authConfig";
import Auth0Client from '@auth0/auth0-spa-js';
const auth0 = new Auth0Client(
domain: authConfig.domain,
client_id: authConfig.clientID,
cacheLocation: 'localstorage',
useRefreshTokens: true
);
const CallbackURI = "http://localhost:3000/login"
export default
// called when the user attempts to log in
login: (url) =>
if (typeof url === 'undefined')
return auth0.loginWithRedirect(
redirect_uri: CallbackURI
)
return auth0.handleRedirectCallback(url.location);
,
// called when the user clicks on the logout button
logout: () =>
return auth0.isAuthenticated().then(function (isAuthenticated)
if (isAuthenticated) // need to check for this as react-admin calls logout in case checkAuth failed
return auth0.logout(
redirect_uri: window.location.origin,
federated: true // have to be enabled to invalidate refresh token
);
return Promise.resolve()
)
,
// called when the API returns an error
checkError: (status) =>
if (status === 401 || status === 403)
return Promise.reject();
return Promise.resolve();
,
// called when the user navigates to a new location, to check for authentication
checkAuth: () =>
return auth0.isAuthenticated().then(function (isAuthenticated)
if (isAuthenticated)
return Promise.resolve();
return auth0.getTokenSilently(
redirect_uri: CallbackURI
)
)
,
// called when the user navigates to a new location, to check for permissions / roles
getPermissions: () =>
return Promise.resolve()
,
;
【讨论】:
【参考方案3】:用auth0原生登录包裹react-admin应用,然后提供react-admindataProvider
一个http客户端,读取auth0存储在本地存储中的jwt令牌会更方便。
【讨论】:
【参考方案4】:我的答案是遵循 react-admin 方法,我使用它的authProvider
,如下所示。主要有两个步骤:
useAuth0
钩子获取需要的数据。
将authProvider
转换为接受上述值的函数,并返回一个类似于默认值的对象。
// In App.js
import authProvider from './providers/authProvider';// my path is changed a bit
const App = () =>
const
isAuthenticated,
logout,
loginWithRedirect,
isLoading,
error,
user,
= useAuth0();
const customAuthProvider = authProvider(
isAuthenticated,
loginWithRedirect,
logout,
user,
);
return (
<Admin
...otherProps
authProvider=customAuthProvider
>
...children
</Admin>
);
// My authProvider.js
const authProvider = (
isAuthenticated,
loginWithRedirect,
logout,
user,
) => (
login: loginWithRedirect,
logout: () => logout( returnTo: window.location.origin ),
checkError: () => Promise.resolve(),
checkAuth: () => (isAuthenticated ? Promise.resolve() : Promise.reject()),
getPermissions: () => Promise.reject('Unknown method'),
getIdentity: () =>
Promise.resolve(
id: user.id,
fullName: user.name,
avatar: user.picture,
),
);
export default authProvider;
就是这样。
【讨论】:
以上是关于如何将 Auth0 与 react-admin 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 django rest api 中的用户与 Auth0 同步