无法保持页面刷新会话

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法保持页面刷新会话相关的知识,希望对你有一定的参考价值。

我有一个使用Rails,React和Webpacker构建的应用程序。我使用的是基于令牌的身份验证,因此,当用户创建帐户或登录时,会在数据库中为其分配令牌。然后,此令牌用于访问用户的个人资料。用户进行身份验证后,配置文件页面加载没有问题,但是出现Rails错误,提示Couldn't find Registration,然后它从我的registration_controller中引用了这一行:registration = Registration.find_by_auth_token!(request.headers[:token])

我尝试从后端接收到令牌时在localStorage中设置令牌,并且当页面使用useEffect钩子在顶层组件上加载时,我尝试从localStorage调用令牌,但似乎没有就像我的React应用程序甚至在出现此错误页面之前就开始渲染。当我收到此错误时,我添加到我的React应用程序的Console.log语句都不会出现在控制台中。

registration_controller.rb

class RegistrationController < ApplicationController
  skip_before_action :verify_authenticity_token

  def index; end

  def custom
    user = Registration.create!(registration_params)
    render json: { token: user.auth_token, id: user.id }
  end

  def profile

    registration = Registration.find_by_auth_token!(request.headers[:token])
    render json: {
      registration: { username: registration.username, email: registration.email, name: registration.name }
    }
  end

  private

  def registration_params
    params.require(:registration).permit(:username, :email, :password, :name)
  end
end

auth.js(操作)

import axios from 'axios';
import reduxStore from '../reduxStore';

export const LOGOUT_START = 'auth/logoutStart';
export const LOGOUT_SUCCESSFUL = 'auth/logoutSuccessful';
export const LOGOUT_ERROR = 'auth/logoutError';
export const LOGIN_START = 'auth/loginStart';
export const LOGIN_SUCCESSFUL = 'auth/loginSuccessful';
export const LOGIN_FAILURE = 'auth/loginFailure';
export const REGISTRATION_START = 'auth/registrationStart';
export const REGISTRATION_SUCCESSFUL = 'auth/registrationSuccessful';
export const REGISTRATION_FAILURE = 'auth/registrationFailure';

export const logout = () => (dispatch) => {
  const headers = { token: localStorage.token };
  // console.log('redux store', reduxStore().getState())
  // console.log('NEW local storage', localStorage);
  dispatch({ type: LOGOUT_START });

  try {
    axios.delete('/logout', { headers })
      .then((res) => {
        dispatch({
          type: LOGOUT_SUCCESSFUL,
          payload: res.data,
        });
      });
  } catch (e) {
    console.error(`logout error: ${e}`);
    dispatch({
      type: LOGOUT_ERROR,
      payload: e,
    });
  }
};

export const login = ({ username, password }) => (dispatch) => {
  const headers = {
    'Content-Type': 'application/json',
  };

  const data = {
    username,
    password,
  };

  dispatch({ type: LOGIN_START });

  try {
    axios.post('/login', data, { headers })
      .then((res) => {
        localStorage.setItem('token', res.data.token);
        dispatch({
          type: LOGIN_SUCCESSFUL,
          payload: res.data,
        });
        // localStorage.setItem('myValueInLocalStorage', event.target.value)
        console.log('localStorage', localStorage);
      });
  } catch (e) {
    console.error(`login error ${e}`);
    dispatch({
      type: LOGIN_FAILURE,
      payload: e,
    });
  }
};

export const createUser = ({
  username,
  password,
  name,
  email,
}) => (dispatch) => {
  const headers = {
    'Content-Type': 'application/json',
  };

  const data = {
    registration: {
      username,
      password,
      name,
      email,
    },
  };

  dispatch({ type: REGISTRATION_START });

  try {
    axios.post('/registration/custom', data, { headers })
      .then((res) => {
        dispatch({
          type: REGISTRATION_SUCCESSFUL,
          payload: res.data,
        });
      });
  } catch (e) {
    console.error(`createUser error: ${e}`);
    dispatch({
      type: REGISTRATION_FAILURE,
      payload: e,
    });
  }
};

我希望此令牌始终在Rails侧的Request对象的Headers中可用,以便当用户刷新窗口时可以显示配置文件页面。

答案

如果标题是“令牌”,rails会将其转换为“ HTTP_TOKEN”,运行puts request.headers.inspect以查看该标题对象中实际包含的内容,我认为您也必须使用字符串而不是符号(headers ['HTTP_TOKEN ']代替标题[:http_token])

另一答案

我能够通过添加一些辅助函数并在React端更改一些逻辑来解决此问题。我在页面加载时,用户登录时和用户注销时开始在本地存储中设置/获取/清除令牌,最终这是在前端管理身份验证状态的更好方法

以上是关于无法保持页面刷新会话的主要内容,如果未能解决你的问题,请参考以下文章

修复 laravel 5 会话在刷新或进入另一个页面后过期?

在页面重新加载/刷新时重置会话?

刷新页面时 select值保持不变

Node.js刷新session过期时间

无法使用 ArrayObjectAdaptor 的 clear() 和 addAll() 刷新/更新浏览片段

无法从 ViewPager 中的另一个片段刷新/更新片段中的列表视图