当 axios 在 React 中请求时,Ruby on Rails 的标头中不包含授权令牌,但它可以与 Postman 一起使用

Posted

技术标签:

【中文标题】当 axios 在 React 中请求时,Ruby on Rails 的标头中不包含授权令牌,但它可以与 Postman 一起使用【英文标题】:Ruby on Rails does not include Authorization token on header when request by axios in React, but it does work with Postman 【发布时间】:2021-12-14 01:01:27 【问题描述】:

我目前正在使用 Ruby on Rails、Devise 和 Devise-JWT 开发后端 API,在前端客户端使用 NextJS,使用 axios 处理请求。我一直在尝试从标头访问授权令牌(一旦用户登录),然后将令牌存储到本地主机中,但它不在请求的标头中。虽然,在 Postman 上进行测试时,登录后请求确实在标头上提供了 Auth。我错过了什么?提前致谢!

【问题讨论】:

你的ApplicationController中有protect_from_forgery吗? 我没有,我通过在 cors 源上设置域并在 cors 资源上公开 ['Authorization'] 来解决它。感谢您的输入! 【参考方案1】:

这将有助于查看您为前端实现 Axios 用户身份验证的代码。

但也许这会有所帮助。

//---------- Reducer -----------
// In your reducer
const authReducer = (state,  type, payload ) => 
  switch (type) 
    case 'LOGIN': 
      localStorage.setItem('authToken', JSON.stringify(payload.auth_token));
      localStorage.setItem('authEmail', JSON.stringify(payload.email));
      return 
        authToken: payload.auth_token,
        authEmail: payload.email,
      ;
    
    case 'YOUROTHER': 
      return   ;
    
    default: 
      
    
  
;

export default authReducer;
//-------------------------------

//---------- Contexts -----------
// In your Contexts auth.js file
import authReducer from '../reducers/auth';

const AuthStateContext = React.createContext();
const AuthDispatchContext = React.createContext();

const token = JSON.parse(localStorage.getItem('authToken'));
const email = JSON.parse(localStorage.getItem('authEmail'));
const initialState = 
  isLoggedIn: !!token,
  authToken: token ? token : null,
  authEmail: email ? email : null,
;

const AuthProvider = ( children ) => 
  const [state, dispatch] = React.useReducer(authReducer, initialState);
  return (
    <AuthStateContext.Provider value=state>
      <AuthDispatchContext.Provider value=dispatch>
        children
      </AuthDispatchContext.Provider>
    </AuthStateContext.Provider>
  );
;
//-------------------------------

//--------- App.js file ---------
// Then wrap the App.js like:
import  AuthProvider  from './contexts/auth';

function App(props) 
  return (
    <AuthProvider>
      <Main ...props />
    </AuthProvider>
  );

//-------------------------------

//------- Your Login Component -------
// Imports
import  useAuthDispatch  from '../../contexts/auth';

// Axios handler 
const baseUrl = 'http://localhost:3001/';
const login = payload => axios.post(`$baseUrlapi/v1/login`, payload);
const authApi = 
  login,
;

// Auth Header Function
const setAuthHeaders = () => 
  // axios request try this
  axios.defaults.headers = 
    Accept: 'applicaion/json',
    'Content-Type': 'application/json',
  ;
  const token = JSON.parse(localStorage.getItem('authToken'));
  const email = JSON.parse(localStorage.getItem('authEmail'));
  //Add token & email to axios header
  if (token && email) 
    axios.defaults.headers['X-Auth-Email'] = email;
    axios.defaults.headers['X-Auth-Token'] = token;
  
;

// Login 
const Login = () => 
  const [initialValues, setInitialValues] = useState(
    email: '',
    password: '',
  );
  
  const authDispatch = useAuthDispatch();
  //const userDispatch = useUserDispatch();

  const handleLogin = async values => 
    const  /*eg. email, password*/  = values;
    try 
      const 
        data:  user, /* should include:*/ auth_token ,
       = await authApi.login( user:  email, password  );
      // your dispatch with payload: auth_token
      authDispatch( type: 'LOGIN', payload:  auth_token, email  ); // passing the token & email via Dispatch
      // The user:  email, password  comes from the userDispatch
      setAuthHeaders(); // Auth Header Func
     catch (error) 
      
    ;

    return (
      <>
        /* your jsx code */
      </>
    );
  
;

export default Login;

//--- # Your Login Component ---

【讨论】:

谢谢 bud,我找到了问题,rails cors 需要设置源域位置,而不仅仅是通配符“”,以便在标题中发送授权.它还必须在 cors 资源 ``` 资源 '' 上公开,标头::any,公开:%w[Authorization],方法:%i[get post put patch delete options head] `` 太好了,rails cors 做到了。我很高兴你知道了。

以上是关于当 axios 在 React 中请求时,Ruby on Rails 的标头中不包含授权令牌,但它可以与 Postman 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

使用 PHP 时发布请求有效,但是当我将 Axios 与 React 一起使用时,它会失败并出现 500 内部错误,我该如何解决?

Axios 发布请求在 React JS 中不起作用

仅当启用 react-native-debugger 时,带有标头的 axios 请求才有效

React Redux Axios:POST 请求未收到来自 redux 状态的凭据

Axios在react js中获取请求时出错

使用 React、Redux 和 Axios 处理异步请求?