Cloudinary上传禁止与我的智威汤逊身份验证方法(Cloudinary upload not

2019-10-29 06:50发布

我主要是由布拉德Traversy一个Udemy教程完成所谓的“MERN堆栈从前到后,”和我跑进一对夫妇类似的错误,试图通过赋予用户上传使用Cloudinary照片选项后,他的应用展开。 这两个错误有关CORS请求。

进入它之前,它可能是重要的了解这个程序是,它使用NPM同时运行的节点服务器,则反应,和/终极版客户端使用相同的NPM运行开发的命令-和不使用中间件处理CORS请求。 所以我的第一个问题是,这是如何设置绕开需要对中间件? 在我看来,像他们仍然在运行单独的服务器...

不管为什么布拉德Traversy的应用程序没有这样的中间件逃脱,当我说我自己的应用程序的着陆页新的行动,做出同样的方式与其他组件做,例如API的请求:

componentDidMount() {
  this.props.getAllAlerts();
}

export function getAllAlerts() {
  const request = axios.get(`${ROOT_URL}/api/alert`);
  return {
    type: GET_ALL_ALERTS,
    payload: request
  };
}

我收到以下错误:“未能加载的http://本地主机:5000 / API /警报 :响应预检请求未通过访问控制检查:否‘访问控制允许来源’标题存在于所请求的。资源产地“ 的http://本地主机:3000 ”因此不允许访问“。

我居然通过添加解决了这个错误完全只是NPM CORS中间件和我的API服务器中使用它。

app.use(cors());

不过,我想知道为什么它在当其他组件做Axios公司的请求,没有必要为它的API首位事情发生了 - 因为也许这将有助于理解为什么跑进一个非常类似的错误以后添加组件时该上传直接从浏览器到Cloudinary照片。 这里的行动:

export const uploadFile = event => {
  const file = event.target.files[0];
  const CLOUDINARY_URL = `https://api.cloudinary.com/v1_1/${myCloudinaryApi}/upload`;
  const CLOUDINARY_UPLOAD_PRESET = CLOUDINARY_UPLOAD_PRESET;
  const formData = new FormData();
  formData.append("file", file);
  formData.append("upload_preset", CLOUDINARY_UPLOAD_PRESET);
  return dispatch => {
    return axios({
      url: CLOUDINARY_URL,
      method: "POST",
      skipAuthorization: true,
      headers: {
        "Content-Type": "application/x-www-form-urlencoded"
      },
      data: formData
    })
      .then(response => {
        dispatch({
          type: UPLOAD_FILE,
          payload: response.data.secure_url
        });
      })
      .catch(function(err) {
        console.log(err);
      });
  };
};

这里的错误:“无法加载https://api.cloudinary.com/v1_1/alertsapi/upload :请求头字段授权不受接入控制允许的报头预检响应允许的。”

我不明白为什么我得到这个尽管使用CORS中间件。

最后,似乎与一个额外的皱纹:这个程序检查一个JWT令牌每次加载顶级组件时间:

// Check for token
if (localStorage.jwtToken) {
  // Set auth token header auth
  setAuthToken(localStorage.jwtToken);
  // Decode token and get user info and exp
  const decoded = jwt_decode(localStorage.jwtToken);
  // Set user and isAuthenticated
  store.dispatch(setCurrentUser(decoded));

  // Check for expired token
  const currentTime = Date.now() / 1000;
  if (decoded.exp < currentTime) {
    // Logout user
    store.dispatch(logoutUser());
    // Clear current Profile
    store.dispatch(clearCurrentProfile());
    // Redirect to login
    window.location.href = "/login";
  }
}

class App extends Component {
  render() {
    return ( 
...

如果我删除此检查,uploadFile行动工作正常。 因此,如果没有其他解决问题,是有办法绕过这个检查只是Cloudinary上传?

在此先感谢任何人的帮助。 让我知道如果我可以提供有关应用程序,可以帮助任何额外的信息。

Answer 1:

我想出了一个解决的第二个问题。 原来,在uploadFile动作Axios的请求包括这是在我的认证检查(如上所示)由功能设置一个授权setAuthToken(localStorage.jwtToken) 这是什么原因造成上面提到的第二个错误。 不幸的是,该功能是从其他文件导入和逃脱我的注意。 这里是:

const setAuthToken = (token`enter code here`) => {
  if (token) {
    // Apply to every request
    axios.defaults.headers.common["Authorization"] = token;
  } else {
    // Delete auth header
    delete axios.defaults.headers.common["Authorization"];
  }
};

该Cloudinary要求不允许这个头。 要删除不需要的头,我添加

delete axios.defaults.headers.common["Authorization"]

右后return dispatch => {uploadFile行动路线。 这允许成功上传的文件,但它也意味着,如果另一个Axios公司要求直接遵循了这一行动,它不会有Authorization头。 在这种情况下,下一个动作确实包括所需授权报头的请求Axios的,所以在与该请求之前该操作回手动添加是必要的:

axios.defaults.headers.common["Authorization"] = localStorage.jwtToken

第二个问题就迎刃而解了。 我仍然不清楚为什么除了我自己的要求,以相同的API引起了CORS错误。



文章来源: Cloudinary upload not allowed with my JWT auth method