反应未针对apache / php进行身份验证的本机axios ios

时间:2019-06-24 20:54:58

标签: php apache react-native zend-framework axios

我要在回家的路上发布此消息,因此请原谅缺少代码,但是我会尽量详细,并在今晚可以添加代码。所以本质上我有一个使用redux和axios的React Native应用程序。简短回顾(请遵循以下代码)可能会说明我做错了事。

Serviceapi.js 创建和导出具有基本URL的基本axios。

const ServiceApi = axios.create({
    baseURL: BASE_URL,
    responseType: 'json'
});

AuthReducer.js 在登录时,使用post方法手动设置Authorization标头。这在android和ios上均有效,返回登录名,我使用授权标头。

return {
    type: PERFORM_LOGIN,
    payload: {
        user: {
            name: username
        },
        request: {
            url: '/login',
            method: 'post',
            headers: { 
                'Authorization': 'Basic ' + basicAuth
            }
        }
    }

登录时,我返回以下redux-axios操作,您可以看到我设置了标头:手动授权,效果很好。

        // On login success, set the authInterceptor responsible for adding headers
        authInterceptor = ServiceApi.interceptors.request.use((config) => {
          console.log(`Attaching Authorization to header ${basicAuth}`);
          config.headers.common.Authorization = basicAuth;
          return config;
        }, (error) => {
          Promise.reject(error);
        });

注销后,我清除了拦截器。我选择在登录和注销时添加和删除,而不是仅仅因为它而一直存在。这可能是个问题,但对于Android来说很好

// Clear the auth interceptor
ServiceApi.interceptors.request.eject(authInterceptor);

同样,这一切在Android上都能正常运行。它看起来正在ios上运行。当我调试拦截器时,它会被调用并设置标头。

但是我在ios上得到了403。详细查看请求后,请求中的android标头与请求中的ios标头之间存在很大差异。请求对象的其余部分相同,但ios和android之间只有_header对象不同。

Android请求

    _headers:
        accept: "application/json, text/plain, */*"

        authorization: "Basic <correct base64 value>"

        content-type: "application/json;charset=utf-8"
__proto__: Object


IOS请求

    _headers:
        accept: (...)

        authorization: (...)

        content-type: (...)

        get accept: ƒ ()
        
set accept: ƒ ()

        get authorization: ƒ ()
        
set authorization: ƒ ()
        
get content-type: ƒ ()

        set content-type: ƒ ()

        __proto__: Object


由于存在差异,因此在查看error.request._headers.authorization;的控制台时设置了一个断点,我得到的内容与Android标头中包含的内容相同。

index.php 后端服务是一个执行$ _SERVER ['PHP_AUTH_USER']的php文件,如果未设置,则会失败403,这是发生了什么事。我没有访问php的权限,只是被告知这是它的用途。

我再次为未提供代码表示歉意,但等到以后有机会我会再说。也许我需要为ios设置其他功能吗?或者也许ios的php需要额外的标题?

要遵循的代码。

EDIT (更新),更新了代码,希望我没有留下任何编码的登录信息。

编辑2 经过进一步调查,这似乎与apache / PHP有关,而不是react-native / axios。我把一个快递服务器放在一起,它模拟与PHP相同的检查: -寻找授权标头 -打印 -根据此数据返回403或200 w /

在模拟器上使用完全相同的应用程序指向http://localhost:3000运行时,我得到了我期望的结果。除此之外,当我在模拟器上时,我实际上无法登录到实时URL(即使我可以在常规设备上登录),我也遇到了403错误,但是这次稍早了。

编辑3

要提供来自服务器的更多信息,这是我已经能够记录的三个请求:

1)这是来自IOS Emulator iPhone8针对快速服务器的情况:

accept:"application/json, text/plain, */*"
accept-encoding:"gzip, deflate"
accept-language:"en-us"
authorization:"Basic <base 64 encoding>"
connection:"keep-alive"
content-length:"0"
host:"localhost:3000"
user-agent:"MobileApp/1 CFNetwork/978.0.7 Darwin/18.5.

2)这是从同一模拟器到apache / PHP(5.3.3),我们可以看到没有Authorization标头。

Accept: application/json, text/plain, */*                                                             
User-Agent: MobileApp/1 CFNetwork/978.0.7 Darwin/18.5.0       
Accept-Language: en-us                                                    
Accept-Encoding: br, gzip, deflate                                        
Connection: keep-alive     

3)这是从Android到apache / PHP(5.3.3):

authorization: Basic <Base 64 encoding> 
Host: api.serviceurl.com
Connection: Keep-Alive                            
Accept-Encoding: gzip                                 
User-Agent: okhttp/3.12.1

编辑4 因此,经过一段时间的搜索和谷歌搜索,事实证明问题出在Zend Framework和fastcgi上,它们会自动删除Authorization标头。奇怪的是,它仅是通过IOS而不是Android来完成的,这真的没有道理。

我们在日志中注意到的事情是,它接受Android和Postman作为POST,但是将IOS请求记录为GET。我不确定这到底是怎么回事,但这似乎又是另一回事。我已经更新了任务,将zend作为标签。有很多关于用ReWriteMod在apache / zend上解决此问题的SO文章,所以我先介绍一下,看看它是否可以解决问题。

**编辑5 ** 到目前为止,我们已经尝试遵循SO文章,该文章要求添加以下内容(Authorization header missing in django rest_framework, is apache to blame?):

SetEnvIfNoCase Authorization ^(.*) -e=PHP_HTTP_AUTH

RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

结果如下:

// IOS
_SERVER[PHP_HTTP_AUTH] = <blank>
_SERVER[HTTP_AUTHORIZATION] = <blank>

// Android
_SERVER[PHP_HTTP_AUTH] = Username
_SERVER[HTTP_AUTHORIZATION] = Basic <Base65 encoded>
_SERVER[PHP_HTTP_PW] = Password

所以我们知道Header Authorization正在进入Apache,但是现在它成为空白。我正在研究其他一些SO答案,但搜索仍在继续...

编辑6

已解决(ish)

1 个答案:

答案 0 :(得分:2)

结果是,对于IOS的请求,它是必需的斜杠。我可以找到此问题描述为的链接https://github.com/square/retrofit/issues/1037

  

对于那些感兴趣的人:我们使用Django作为后端,默认情况下,   不在端点上提供尾部斜杠Django从非斜杠重定向   端点到斜杠端点。

现在,我们不使用Django,但显然我们的Zend配置是 同样的问题-Android能够重定向而没有问题,而IOS却没有。关于任务的另一条评论指出:

  

当跨主机(连接)重定向时,OkHttp剥离“ Authorization”标头   通过原始主机的3xx响应。

这似乎不太准确,因为Android使用的是OkHttp,并且工作正常。看来使用达尔文的IOS遇到了问题。

编辑 我从最初的帖子中忘记了其他内容,我还不得不将拦截器从config.headers.common.Authorization = ...行更改为config.headers.Authorization = ...,出于某种原因,它保留了原意。原始方式将授权转换为授权,而后者将其保留为授权。不知道这是否是一个问题,但是我还是做到了。

// On login success, set the authInterceptor responsible for adding headers
authInterceptor = ServiceApi.interceptors.request.use((config) => {
      console.log(`Attaching Authorization to header ${basicAuth}`);
      config.headers.Authorization = basicAuth;
      return config;
    }, (error) => {
      Promise.reject(error);
    });