使用 next.js 和 Parse Server 在 getInitialProps 内重定向

Posted

技术标签:

【中文标题】使用 next.js 和 Parse Server 在 getInitialProps 内重定向【英文标题】:Redirect inside a getInitialProps with next.js and Parse Server 【发布时间】:2020-04-13 08:49:22 【问题描述】:

编辑:

我在用户连接时设置了一个 cookie,并将令牌存储在 cookie 中。通过GetInitialPropsi 访问cookie,我检查会话是否设置为用户。

似乎只有当我使用链接访问此页面时才有效:例如主页到此页面,但是当我输入网址时它不起作用。

我正在使用 npm install --save next-cookies 来检索 cookie: https://www.npmjs.com/package/next-cookies

很抱歉,这可能是一个愚蠢的问题,但我仍在学习......

这是我的页面 Login.js 的全部代码


import React,  Component, useState  from 'react'
import Parse from 'parse'
import Snackbar from '@material-ui/core/Snackbar';
import Cookies from 'js-cookie'
import cookies from 'next-cookies'

export default function login() 

    const [state, setState] = React.useState(
        username: "",
        password: "",
    
    )

    const [error, setError] = useState(false)

    async function handleConnection() 
        try 
            const user = await Parse.User.logIn(state.username, state.password)
            console.log(user)

            var currentUser = Parse.User.current();
            const token = currentUser.getSessionToken()
            //console.log(token)
            Cookies.set('token', token,  expires: 365 )
            setError(false)
         catch (e) 
            setError(true)
        
    
    function handleChange(evt) 
        const value = evt.target.value;
        setState(
            ...state,
            [evt.target.name]: value
        );
    

    return (
        <div className="notConnected container-fluid">
            <div className="containerFormLogin">
                <h1>Connectez-vous !</h1>
                <p>error ? "Nom d'utilisateur ou mot de passe incorrect" : ''</p>
                <label>Nom d'utilisateur ou mail</label>
                <input type="text" name="username" onChange=handleChange />
                <label>Mot de passe</label>
                <input type="password" name="password" onChange=handleChange />
                <button className="pulse" onClick=handleConnection>Se connecter</button>
                <p>Pas encore de compte ? Inscrivez-vous par ici !</p>
                <Snackbar
                    anchorOrigin= vertical: "bottom", horizontal: "center" 
                    open=error
                    autoHideDuration=3000
                    message=<span id="message-id">Impossible de se connecter, vérifier vos informations de connexion</span>
                    ContentProps=
                        "aria-describedby": "message-id"
                    
                ></Snackbar>
            </div>
            <style jsx>`

                .notConnected
                
                    background-image: url('/images/notConnected.svg');
                    height: 100vh;
                    width: 100%;
                    background-position: center;
                    background-size: cover;
                    background-repeat: no-repeat;
                    display: flex,
                
                p:empty
                
                    margin:0 !important;
                
                .containerFormLogin
                
                    width: 400px;
                    background-color: rgba(255,255,255, 0.8);
                    box-shadow: rgba(0,0,0, 0.5) 10px 10px 10px;
                    border-radius: 10px;
                    display: flex;
                    flex-direction: column;
                    padding: 30px;
                    margin:auto;
                    transition: all .2s ease-in;
                
                .containerFormLogin:hover
                
                    background-color: rgba(255,255,255, 1);
                
                .containerFormLogin h1
                
                    margin-bottom: 40px;
                    font-family: 'Raleway', sans-serif;
                    font-size: 25px;
                    text-align: center;
                
                .containerFormLogin p
                
                    font-size: 12px;
                    font-family: 'Raleway', sans-serif;
                    margin-top: 10px;
                
                .containerFormLogin label
                
                    font-size: 12px;
                    font-family: 'Raleway', sans-serif;
                
                .containerFormLogin input
                
                    margin-bottom: 20px;
                    font-family: 'Raleway', sans-serif;
                    font-size: 15px;
                    padding-top: 10px;
                    padding-bottom: 10px;

                
                .error
                
                    border-color: red;
                
                button 
                
                background: none;
                border: 2px solid;
                font: inherit;
                line-height: 1;
                padding: 1em 2em;
                color:  #ef6eae;
                -webkit-transition: 0.25s;
                transition: 0.25s;
                
                button:hover, button:focus 
                border-color: #ef8f6e;
                color: #ef8f6e;
                
                .pulse:hover,
                .pulse:focus 
                -webkit-animation: pulse 1s;
                        animation: pulse 1s;
                box-shadow: 0 0 0 2em rgba(255, 255, 255, 0);
                

                @-webkit-keyframes pulse 
                0% 
                    box-shadow: 0 0 0 0 #ef8f6e;
                
                

                @keyframes pulse 
                0% 
                    box-shadow: 0 0 0 0 #ef8f6e;
                
                

            `</style>
        </div >
    )


login.getInitialProps = (ctx) => 

    const allCookies = cookies(ctx).token;

    const UserToken = Parse.User.me(allCookies)
    if (UserToken) 
        // the user is connected so we do the redirection beacause when he's connected he can't have access to this page
        return (
            UserToken
        )
     else 
        // Do something else

    




编辑#2:

当我通过主页之类的链接到达登录页面时,出现此错误

Unhandled Rejection (TypeError): res is undefined

当我重新加载页面或通过他的网址访问时,他给了我另一个错误:

ReferenceError: localStorage is not defined

这是我的 getInitialProps:

connexion.getInitialProps = ( ctx, res ) => 

    const cookies = Cookies.get('tokenUserParse');

    const UserToken = Parse.User.me(cookies)
    if (UserToken) 
        // the user is connected so we do the redirection beacause when he's connected he can't have access to this page

        res.writeHead(403, 
            Location: '/'
        );
        res.end();

     else 
        // Do something else

    

【问题讨论】:

服务器端不能使用Parse.User.current()函数。 好的,谢谢,所以当我使用Parse.User.current() 时,我需要设置渲染此组件或其他组件的条件 现在我相信您有不同的问题:) 当您的用户登录您的前端时,您需要将其会话令牌存储在 cookie 中。在您的getInitialProps 函数中,您必须检查它是在客户端还是在服务器中运行。在客户端时,您可以只使用 Parse.User.current(),但在服务器中时,您必须从 cookie 中检索会话令牌并使用 Parse.User.me(sessionToken) 返回登录的用户。试一试并编辑问题/使用您的代码打开一个新问题。 请帮忙,我用我的代码编辑我的问题,我不确定我的方法是否正确...... 看来您的方向是正确的。什么现在不起作用? 【参考方案1】:

您需要了解getInitialProps 中的相同代码将在服务器(Node.js 环境)和浏览器(javascript)中运行。一些库在这两种环境下都能很好地工作,但有些库不能。因此,有时您需要根据代码运行的环境执行不同的操作。这样的事情应该可以解决您的问题:

const isServer = typeof window === 'undefined';

const Parse = isServer ? require('parse/node') : require('parse');

connexion.getInitialProps = async ( ctx, res ) => 

    const cookies = Cookies.get('tokenUserParse');

    const UserToken = await Parse.User.me(cookies)
    if (UserToken) 
        // the user is connected so we do the redirection beacause when he's connected he can't have access to this page

        if (isServer) 
            res.writeHead(302, 
                Location: '/'
            );
            res.end();
         else 
            document.location.href = '/'
        
     else 
        // Do something else

    

【讨论】:

以上是关于使用 next.js 和 Parse Server 在 getInitialProps 内重定向的主要内容,如果未能解决你的问题,请参考以下文章

Next.js 配置接口跨域代理转发

错误:在 next.js 中调用 `server.createHandler()` 之前必须`await server.start()`

AWS Amplify 和 Next.JS with GraphQL Server Error No current user from getStaticPaths

Next JS 与 Apollo 和 MongoDB 的连接

如何使用 iptables 和 parse-server (Parse Server) 将 HTTP 重定向到 HTTPs

启动和停止 Parse-Server 和 Parse-Server 仪表板