如何解决这是将 Next.js + NextAuth 与 Django Rest Framework API 连接的正确且安全的方式吗?
我一直在使用 Django Rest Framework 开发带有自定义后端的 Next.js 应用程序,主要关注社交平台(Google、Github 等)的身份验证。这是我想要使用的流程:
- 让 NextAuth 为社会认证做繁重的工作。例如,当用户想要使用他/她的 Google 帐户登录时,它会返回一个访问令牌和一个 id 令牌。
- 将 Google 返回的 id 令牌和访问令牌放入 NextAuth 会话对象中。
- 在前端,使用会话对象中的这两个令牌向 DRF 后端发出 POST 请求,后端基本上接受访问令牌和 id 令牌,并返回访问令牌和刷新令牌。注意。 DRF 后端具有
dj-rest-auth
和django-allauth
设置来处理社交身份验证。 - DRF 后端以 HTTPOnly cookie 的形式发回令牌。因此,下次我想向 DRF API 发出请求时,cookie 应该随请求一起传递。
这是正确和安全的,还是我在踢自己的脚?
我的上下文代码:
index.tsx
import React,{ useEffect } from "react";
import { signIn,signOut,useSession } from "next-auth/client";
import { Typography,Button,Box } from "@material-ui/core";
import { makeUrl,BASE_URL,SOCIAL_LOGIN_ENDPOINT } from "../urls";
import axios from "axios";
axios.defaults.withCredentials = true;
function auth() {
const [session,loading] = useSession();
useEffect(() => {
const getTokenFromServer = async () => {
// TODO: handle error when the access token expires
const response = await axios.post(
// DRF backend endpoint,api/social/google/ for example
// this returns accessToken and refresh_token in the form of HTTPOnly cookies
makeUrl(BASE_URL,SOCIAL_LOGIN_ENDPOINT,session.provider),{
access_token: session.accessToken,id_token: session.idToken,},);
};
if (session) {
getTokenFromServer();
}
},[session]);
return (
<React.Fragment>
<Box
display="flex"
justifyContent="center"
alignItems="center"
m={5}
p={5}
flexDirection="column"
>
{!loading && !session && (
<React.Fragment>
<Typography variant="button">Not logged in</Typography>
<Button
variant="outlined"
color="secondary"
onClick={() => signIn()}
>
Login
</Button>
</React.Fragment>
)}
{!loading && session && (
<React.Fragment>
<Typography>Logged in as {session.user.email}</Typography>
<pre>{JSON.stringify(session,null,2)}</pre>
<Button
variant="outlined"
color="primary"
onClick={() => signOut()}
>
Sign Out
</Button>
</React.Fragment>
)}
</Box>
</React.Fragment>
);
}
export default auth;
api/auth/[...nextauth].ts
import NextAuth from "next-auth";
import { InitOptions } from "next-auth";
import Providers from "next-auth/providers";
import { NextApiRequest,NextApiResponse } from "next";
import axios from "axios";
import { BASE_URL,makeUrl } from "../../../urls";
import { AuthenticatedUser,CustomSessionObject } from "../../../types";
import { GenericObject } from "next-auth/_utils";
const settings: InitOptions = {
providers: [
Providers.Google({
clientId: process.env.GOOGLE_CLIENT_ID,clientSecret: process.env.GOOGLE_CLIENT_SECRET,authorizationUrl:
"https://accounts.google.com/o/oauth2/v2/auth?prompt=consent&access_type=offline&response_type=code",}),],secret: process.env.NEXT_AUTH_SECRET,session: {
maxAge: 6 * 60 * 60,// 6 hours
},callbacks: {
async signIn(user: AuthenticatedUser,account,profile) {
if (account.provider === "google") {
const { accessToken,idToken,provider } = account;
user.accessToken = accessToken;
user.idToken = idToken;
user.provider = provider;
return true;
}
return false;
},async session(session: CustomSessionObject,user: AuthenticatedUser) {
session.accessToken = user.accessToken;
session.idToken = user.idToken;
session.provider = user.provider;
return session;
},async jwt(token,user: AuthenticatedUser,profile,isNewUser) {
if (user) {
token.accessToken = user.accessToken;
token.idToken = user.idToken;
token.provider = user.provider;
}
return token;
},};
export default (req: NextApiRequest,res: NextApiResponse) => {
return NextAuth(req,res,settings);
};
会话对象是否足够安全以存储令牌这一事实让我感到压力很大。我还想实现一种机制,在访问令牌过期时使用刷新令牌刷新访问令牌。
解决方法
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。