可以通过Express-Session管理_app的登录状态吗?

时间:2019-08-02 18:51:59

标签: next.js express-session

是否可以使登录状态(例如以_app状态的用户对象的形式)/良好做法?

我在_app上有一个登录模式,该模式可以在成功的身份验证服务器端之后返回用户数据对象,然后将该对象设置为_app状态。 通过Context API,我可以将此登录状态移交给我的页面。

_app刷新时,有两种可能的方法:

SSR:在getInitialProps中,我可以从(express-session)req.session获取用户数据对象,并将其设置为构造函数中的_app状态。 CSR:当_app由于客户端导航而刷新时,状态保持不变,我的用户对象也保持不变。构造函数仅在SSR时调用。

所以我永远不需要cookie。...对吗?

编辑:关于构造函数,我错了。似乎它也被称为客户端。以前没有意识到这一点。...似乎有些奇怪。

EDIT2:奇怪的是,服务器和客户端日志上都记录了“ _app已构建” ...添加了_app代码段

class CustomApp extends App {
    constructor(props) {
        super(props);
    // getInitialProps is static, therefore called before any other method (even constructor!). 
    // So in constructor we can already use the pageProps props which is returned by getInitialProps.
    this.state = { user: this.props.user, openModal: false, csrfLoginToken: this.props.csrfLoginToken};     
    console.log("_app constructed. csfr=", this.state.csrfLoginToken);
}

static async getInitialProps({ Component, ctx }) {
    let pageProps = {};             

    if (Component.getInitialProps) {
        pageProps = await Component.getInitialProps(ctx);
    }

    if (!process.browser) {
        console.log("_app renders on server, csrf: ",ctx.res.locals.csrfLoginToken);

        //CSRF Token in res.locals when user not set
        const csrfLoginToken = ctx.res.locals.csrfLoginToken
            ? ctx.res.locals.csrfLoginToken
            : null;

  //set user      
  //needed for full browser refreshes (via link, adress bar etc..) 
  //because _app loses state in that case, so we have to get it from session during ssr call
  const user = ctx.req.session.user 
    ? (ctx.req.session.user)
            : null;

        //status code
        const {statusCode} = ctx.res            

        return { ...pageProps, csrfLoginToken, user, statusCode};       
    } 

    console.log("_app renders on client.");

    return { ...pageProps}; 
    }
...
    handleNormalLogin = async (values) => {
    console.log("_app got normal submit : csrf token to be sent:",this.state.csrfLoginToken);
    this.handleClose();

    const response = await apiLogin(values.email, values.password, this.state.csrfLoginToken);

    if (response.ok) {
        try {
            const user = await response.json();
            this.setState({ user: user });
            this.setState({ csrfLoginToken: null });
            Router.push({ pathname: "/bookings" }); //client-side navigation!               
        } catch (err) {
            console.log("profile_err", err);
        }
    }
};

0 个答案:

没有答案