29
loading...
This website collects cookies to deliver better user experience
Don't roll your own crypto.
Auth0 is easy to implement, adaptable authentication and authorization platform.
Basically, we make your login box awesome.
Implicit Flow
.API
, this will help us define scopes like data:read
, data:write
,... whatever. These scopes are all custom and they can be whatever we want, essentially labels for our business logic.Name
: can be anythingIdentifier
: This should just be something like https://<BASE_URL>/api
(example: https://127.0.0.1:5000/api
). This can not be changed later.Permissions
tab in the API and create some scopes/permissions for our users. You can add data:read
for simplicity, this can be finetuned to as granular as you like.+ Create Application
and choosing Single Page Web Applications
. You can put whatever name you like.Machine to Machine App
through the Applications Page by + Create Application
.ssl_context="adhoc"
to the run()
method of the Flask backend:
app.run(ssl_context="adhoc")
localhost
in Application URIs, for which you can simply use https://127.0.0.1:<PORT>
(example: https://127.0.0.1:5000
)Refresh Token Rotation
, Refresh Token Expiration (Absolute and Inactivity)
are enabled. Which will allow us to persist tokens with the browser localstorage
. These settings can be located below Application URIs
Auth0Provider
component:import React from "react";
import { useNavigate } from "react-router-dom";
import { Auth0Provider } from "@auth0/auth0-react";
const Auth0ProviderWithHistory = ({ children }) => {
const navigate = useNavigate();
const onRedirectCallback = (appState) => {
navigate(appState?.returnTo || window.location.pathname);
};
return (
<Auth0Provider
domain="YOUR_DOMAIN"
clientId="YOUR_DOMAIN"
redirectUri={window.location.origin}
scope="read:data"
useRefreshTokens
cacheLocation="localstorage"
onRedirectCallback={onRedirectCallback}
>
{children}
</Auth0Provider>
);
};
export default Auth0ProviderWithHistory;
domain
, clientId
, redirectUri
are defined like from the quickstart.scope
requests that this user be granted the permission that we defined in the API
useRefreshTokens
tells Auth0 to also return refresh tokens along with the access token. Learn more
cacheLocation
using localstorage
for this means that the tokens are saved locally on the browser. This is secure since we enabled Refresh Token Rotation
, Refresh Token Expiration (Absolute and Inactivity)
. Auth0 explains why very well
onRedirectCallback
essentially returns the user to the page where they were redirected to login.<App>
, make sure Auth0 Provider is a child of that element.ColorModeScript
is a Chakra UI thing where you can set default colour schemes.ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<ChakraProvider>
<Auth0ProviderWithHistory>
<ColorModeScript initialColorMode={theme.config.initialColorMode} />
<App />
</Auth0ProviderWithHistory>
</ChakraProvider>
</BrowserRouter>
</React.StrictMode>,
document.getElementById("root")
);
withAuthenticationRequired
import React from "react";
import { withAuthenticationRequired } from "@auth0/auth0-react";
import Loading from "../components/Loading";
function Page() {
return (
<div>
<h1>New Page</h1>
</div>
);
}
export default withAuthenticationRequired(Page, {
onRedirecting: () => <Loading />,
});
Bearer
token as part of the HTTP request. As also documented here by Auth0 in the quickstart.# This doesn't need authentication
@bp.route("/test/public")
@cross_origin(headers=["Content-Type", "Authorization"])
def public():
response = (
"Hello from a public endpoint! You don't need to be authenticated to see this."
)
return jsonify(message=response)
# This needs authentication
@bp.route("/test/private")
@cross_origin(headers=["Content-Type", "Authorization"])
@requires_auth
def private():
response = (
"Hello from a private endpoint! You need to be authenticated to see this."
)
return jsonify(message=response)
# This needs authorization
@bp.route("/test/private-scoped")
@cross_origin(headers=["Content-Type", "Authorization"])
@requires_auth
def private_scoped():
if requires_scope("read:data"):
response = "Hello from a private endpoint! You need to be authenticated and have a scope of read:messages to see this."
return {"message": response}
raise AuthError(
{
"code": "Unauthorized",
"description": "You don't have access to this resource",
},
403,
)
cross-origin
to enable CORS on a per endpoint basis; requires_auth
to extract Bearer
tokens and validate it with Auth0.