gpt4 book ai didi

authentication - 这是将 Next.js + NextAuth 与 Django Rest Framework API 连接的正确且安全的方式吗?

转载 作者:行者123 更新时间:2023-12-04 01:06:28 25 4
gpt4 key购买 nike

我一直在使用 Django Rest Framework 开发带有自定义后端的 Next.js 应用程序,主要关注社交平台(Google、Github 等)的身份验证。这是我想要使用的流程:

  • 让 NextAuth 为社会认证做繁重的工作。例如,当用户想要使用他/她的 Google 帐户登录时,它会返回一个访问 token 和一个 id token 。
  • 将谷歌返回的 id token 和访问 token 放入 NextAuth session 对象中。
  • 在前端,使用 session 对象中的这两个 token 向 DRF 后端发出 POST 请求,后端基本上接受访问 token 和 id token ,并返回访问 token 和刷新 token 。注意。 DRF 后端有 dj-rest-authdjango-allauth设置以处理社交身份验证。
  • DRF 后端以 HTTPOnly cookie 的形式发回 token 。所以,下次我想向 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, SOCIAL_LOGIN_ENDPOINT, 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, account, 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);
    };

    session 对象是否足够安全以存储 token 这一事实让我感到压力很大。我还想实现一种机制,在访问 token 过期时使用刷新 token 刷新访问 token 。

    最佳答案

    随着时间的推移,我最终解决了这个问题。我写了一篇由两部分组成的文章,概述了我是如何解决它的,可以找到 herehere

    关于authentication - 这是将 Next.js + NextAuth 与 Django Rest Framework API 连接的正确且安全的方式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66288809/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com