当 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 内部错误,我该如何解决?
仅当启用 react-native-debugger 时,带有标头的 axios 请求才有效