2017-06-13 29 views
4

我目前在我的React和Play应用中实现了OAuth与LinkedIn的登录,并且在尝试重定向到运行时出现CORS错误在我的开发环境授权页面:Oauth重定向返回没有'Access-Control-Allow-Origin'标题出现在请求的资源上

XMLHttpRequest cannot load https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_i…basicprofile&redirect_uri=http%3A%2F%2Flocalhost%3A9000%2Fusers%2Flinkedin. Redirect from 'https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_i…basicprofile&redirect_uri=http%3A%2F%2Flocalhost%3A9000%2Fusers%2Flinkedin' to 'https://www.linkedin.com/uas/login?session_redirect=%2Foauth%2Fv2%2Flogin-s…' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

我有以下设置:

  • 游戏服务器在本地主机上运行:9000
  • 作出反应的应用程序(创建通过创建反应的-APP)在本地主机上运行:3000

我的JS代码调用/auth/linkedin端点其执行如下:

Action { implicit req: RequestHeader => 
    val csrfToken = CSRF.getToken.get.value 
    Redirect(linkedinUrl(oauthConfig.linkedinClientId, csrfToken)).withSession("state" -> csrfToken) 
} 

我有我的Play应用程序设置为妥善处理CORS。

我的反应程序只是使上述终端的请求通过爱可信:

axios.get('/auth/linkedin')

这与重定向到LinkedIn AUTH页面,然后给我的错误一个303响应。

如何在此dev设置中正确使用CORS策略?我试着添加以下到我的package.json作为创建反应的应用程序内的文档推荐:

"proxy": "http://localhost:9000",

而且我也尝试设置请求头"Access-Control-Allow-Origin" : "*"对重定向的播放服务器没有成功。

请注意,转到localhost:9000/auth/linkedin会正确重定向。

回答

3

https://www.linkedin.com/oauth/v2/authorization响应显然不包括Access-Control-Allow-Origin响应标题,并且因为它们没有,您的浏览器会阻止您的前端JavaScript代码访问响应。

您可以对自己的前端JavaScript代码进行任何更改,也不需要后端配置设置,以便您的前端JavaScript代码以您直接尝试https://www.linkedin.com/oauth/v2/authorization的方式提出请求并成功获取响应。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS更详细的解释,但其要点是,对于CORS,请求发送到的服务器必须配置为发送Access-Control-Allow-Origin响应标头,也不是您自己的后端服务器。

反正https://developer.linkedin.com/docs/getting-started-js-sdk有介绍如何申请授权用户跨来源,这似乎是眼前这个官方的文档:

<script type="text/javascript" src="//platform.linkedin.com/in.js"> 
    api_key: [API_KEY] 
    onLoad: [ONLOAD] 
    authorize: [AUTHORIZE] 
    lang:  [LANG_LOCALE] 

IN.User.authorize(callbackFunction, callbackScope); 
</script> 

而且https://developer.linkedin.com/docs/signin-with-linkedin有其他文档另一个身份验证流程:

<script type="in/Login"></script> <!-- Create the "Sign In with LinkedIn" button--> 

<!-- Handle async authentication & retrieve basic member data --> 
<script type="text/javascript"> 

    // Setup an event listener to make an API call once auth is complete 
    function onLinkedInLoad() { 
     IN.Event.on(IN, "auth", getProfileData); 
    } 

    // Handle the successful return from the API call 
    function onSuccess(data) { 
     console.log(data); 
    } 

    // Handle an error response from the API call 
    function onError(error) { 
     console.log(error); 
    } 

    // Use the API call wrapper to request the member's basic profile data 
    function getProfileData() { 
     IN.API.Raw("/people/~").result(onSuccess).error(onError); 
    } 

</script> 
+0

感谢您的有用信息!奇怪的是,如果我只是做一些像'Linkedin'点击链接的工作很好,任何想法为什么会通过axios请求通过失败?我认为只是做一个链接对我来说可能是最简单的。 –

+1

当您点击创建* navigation *的链接时,这与从前端JavaScript代码发出请求并使用响应非常不同。浏览器不会阻止跨浏览器的导航(否则整个网络将无法工作...) - 但浏览器确实阻止前端JavaScript代码能够从跨源请求获取响应,除非发送请求的站点/服务器指示它正在选择接收这样的请求。而服务器选择接收跨域请求的方式是,它们在其响应中包含Access-Control-Allow-Origin标头 – sideshowbarker

+0

@sideshowbarker非常感谢您的帮助,您节省了我的时间。几乎在运行谷歌oauth相同,我尝试了所有可能的方式,但没有运气!最后你的评论解决了我的问题。我没有调用api调用,而是将它作为锚标记,它工作正常。非常感谢。 –

相关问题