Maison  >  Article  >  cadre php  >  Solution au problème inter-domaines de session dans thinkphp

Solution au problème inter-domaines de session dans thinkphp

尚
avant
2020-06-01 09:10:243446parcourir

Solution au problème inter-domaines de session dans thinkphp

Lorsqu'il est utilisé localement, tout est normal ; le projet back-end et le projet front-end sont déployés sur le serveur, et tout est normal après que le projet back-end soit déployé ; déployé sur le serveur et que l'accès inter-domaines est configuré pour autoriser l'accès inter-domaines, le projet frontal local Lors de l'utilisation de l'interface du projet back-end sur le serveur, un problème survient :

Tout d'abord, utilisez facteur pour tester l'interface pour obtenir le code de vérification de l'image et l'interface pour vérifier le code de vérification de l'image. C'est normal.

Ensuite, utilisez l'interface obtenir le code de vérification de l'image en html, cela fonctionne bien ; enfin, utilisez l'interface du code de vérification de l'image en JS, ça se passe mal ! ! !

Analyse

Grâce à la description du problème, nous pouvons voir que le problème se produit dans tous les domaines. Il y a donc deux possibilités : l'une est due au fait que les paramètres inter-domaines sont incorrects ; l'autre est due à un problème avec thinkphp lui-même.

En utilisant une autre configuration inter-domaines, le problème existe toujours. C'est un problème avec thinkphp lui-même. Après avoir recherché des informations, le problème se situe dans l'inter-domaine de la session thinkphp.

Solution inter-sous-domaines

En fait, qu'il s'agisse de ThinkPHP ou de PHP lui-même, session.cookie_domain doit être défini lors de la résolution de problèmes inter-domaines de session.
Les principales solutions au problème de session cross-domain sont les suivantes :

Le premier cas : S'il n'y a pas de fichier .htaccess dans le répertoire, c'est à dire si l'url n'est pas pseudo-statique , puis Ajoutez :

ini_set('session.cookie_domain',".domain.com");//跨域访问Session

à la première ligne de conf/config.php Si vous activez le débogage, cela fonctionnera ! Mais si le débogage est désactivé, cela ne fonctionne pas !

Deuxième cas : S'il y a un fichier .htaccess dans votre répertoire, alors vous ajoutez dans le répertoire racine, la première ligne de index.php :

Cette méthode n'a pas d'importance si elle est activé ou non. Cela fonctionne pour le débogage !

Cependant, notre problème n'est pas un problème inter-sous-domaines, mais complètement inter-domaines, donc la méthode ci-dessus ne fonctionne pas.

Solution interdomaine complète

Obtenir une demande de code de vérification d'image

Afficher les informations de demande pour obtenir le code de vérification d'image, les en-têtes de demande sont :

Accept:image/webp,image/*,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4
Connection:keep-alive
Cookie:pma_lang=zh_CN; pma_collation_connection=utf8_unicode_ci; pma_iv-1=wnpO4gv0eQRW1AMHmGr2ww%3D%3D; pmaUser-1=weZPqS0%2BW7nzFUVHRdqcfA%3D%3D
Host:api.voidking.com
Referer:http://localhost/ajax/ajax.html
User-Agent:Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36

Les en-têtes de réponse sont :

Access-Control-Allow-Origin:*
Cache-Control:post-check=0, pre-check=0
Cache-Control:private, max-age=0, no-store, no-cache, must-revalidate
Connection:keep-alive
Content-Type:image/png
Date:Sun, 27 Nov 2016 12:10:44 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Pragma:no-cache
Server:nginx
Set-Cookie:PHPSESSID=721t4sqanvsii550m1dk8gq1o3; path=/; domain=.voidking.com
Transfer-Encoding:chunked

Demande de code de vérification de vérification

Afficher les informations de la demande pour le code de vérification de vérification, les en-têtes de demande sont :

Accept:application/json, text/javascript, */*; q=0.01
Accept-Encoding:gzip, deflate
Accept-Language:zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4
Connection:keep-alive
Content-Length:9
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Host:api.voidking.com
Origin:http://localhost
Referer:http://localhost/ajax/ajax.html
User-Agent:Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36

Les en-têtes de réponse sont :

Access-Control-Allow-Origin:*
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/html; charset=UTF-8
Date:Sun, 27 Nov 2016 12:13:21 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Pragma:no-cache
Server:nginx
Set-Cookie:PHPSESSID=149t0hhs2icqaaemvp39onkgp4; path=/; domain=.voidking.com
Transfer-Encoding:chunked
Vary:Accept-Encoding

Obtenir à nouveau la demande de code de vérification d'image

Les en-têtes de demande sont :

Accept:image/webp,image/*,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4
Cache-Control:max-age=0
Connection:keep-alive
Cookie:pma_lang=zh_CN; pma_collation_connection=utf8_unicode_ci; pma_iv-1=wnpO4gv0eQRW1AMHmGr2ww%3D%3D; pmaUser-1=weZPqS0%2BW7nzFUVHRdqcfA%3D%3D; PHPSESSID=721t4sqanvsii550m1dk8gq1o3
Host:api.voidking.com
Referer:http://localhost/ajax/ajax.html
User-Agent:Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36

Les en-têtes de réponse sont :

Access-Control-Allow-Origin:*
Cache-Control:private, max-age=0, no-store, no-cache, must-revalidate
Cache-Control:post-check=0, pre-check=0
Connection:keep-alive
Content-Type:image/png
Date:Sun, 27 Nov 2016 13:26:21 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Pragma:no-cache
Server:nginx
Transfer-Encoding:chunked

Comparaison de trois requêtes

Solution au problème inter-domaines de session dans thinkphp

Pour la première requête pour obtenir le code de vérification de l'image, il n'y a pas de PHPSESSID dans le cookie, donc Set- Le cookie est inclus dans les informations de retour. Dans la deuxième demande pour obtenir le code de vérification de l'image, le cookie contient PHPSESSID, donc Set-Cookie n'est pas inclus dans les informations de retour.

Et le PHPSESSID dans les informations Set-Cookie renvoyées par la première requête est le même que le PHPSESSID dans les informations de la requête Cookie dans la deuxième requête.

La requête ajax pour vérifier le code de vérification de l'image n'a pas de cookie, et naturellement il n'y a pas de PHPSESSID, donc les informations de retour contiennent également Set-Cookie.

On voit que nous devons apporter quelques modifications sur le front-end pour envoyer la requête avec Cookie.

Paramètres jquery front-end

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>jquery</title>
</head>
<body>
    <p>
        <img src="http://api.voidking.com/owner-bd/index.php/Home/CheckCode/getPicCode" alt="">
        <input type="text" id="picCode">
        <input type="button" id="send" value="验证">
    </p>
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
    $(function(){
        $(&#39;#send&#39;).click(function(){
            //console.log(document.cookie);
            $.ajax({
                url: &#39;http://api.voidking.com/owner-bd/index.php/Home/CheckCode/checkPicCode&#39;,
                type: &#39;POST&#39;,
                crossDomain: true,
                xhrFields: {
                    withCredentials: true
                },
                dataType: &#39;json&#39;,
                data: {code: $(&#39;#picCode&#39;).val()},
                success: function(data){
                    console.log(data);
                },
                error: function(xhr){
                    console.log(xhr);
                }
            });
        });
    });
</script>
</body>
</html>

L'erreur signalée lors de la demande est la suivante :

A wildcard &#39;*&#39; cannot be used in the &#39;Access-Control-Allow-Origin&#39; header when the credentials flag is true. Origin &#39;http://localhost&#39; is therefore not allowed access. The credentials mode of an XMLHttpRequest is controlled by the withCredentials attribute.

Une erreur interdomaine s'est produite. Cela peut être. vu que le backend doit également apporter quelques modifications, afin qu'il puisse recevoir des cookies inter-domaines.

Paramètres nginx backend

add_header Access-Control-Allow-Origin http://localhost;
add_header Access-Control-Allow-Credentials true;

Remarque :
Lorsque le paramètre Access-Control-Allow-Credentials côté serveur est vrai, le paramètre Access-Control-Allow- Paramètre d'origine La valeur ne peut pas être *.

Une fois le backend nginx configuré, la requête ajax de jquery est normale et les cookies peuvent être transportés le backend reçoit et renvoie les données normalement.

Étant donné que la requête ajax d'Angular est différente de celle de jquery, nous devons également étudier comment Angular envoie des requêtes inter-domaines contenant des cookies.

Paramètres angulaires du front-end

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>angular</title>
    <script src="http://cdn.static.runoob.com/libs/angular.js/1.4.6/angular.min.js"></script>
</head>
<body ng-app="myApp" >
    <p ng-controller="myCtrl">
        <img src="http://api.voidking.com/owner-bd/index.php/Home/CheckCode/getPicCode" alt="">
        <input type="text" id="picCode" ng-model="picCode">
        <input type="button" ng-click="send()"  value="验证">
    </p>
<script>
    var app = angular.module(&#39;myApp&#39;, []);
    app.controller(&#39;myCtrl&#39;, function($scope, $http, $httpParamSerializer) {
        $scope.send = function(){
            $http({
                method:&#39;POST&#39;,
                url:&#39;http://api.voidking.com/owner-bd/index.php/Home/CheckCode/checkPicCode&#39;,
                headers:{
                    &#39;Content-Type&#39;:&#39;application/x-www-form-urlencoded&#39;
                },
                withCredentials: true,
                dataType: &#39;json&#39;,
                data: $httpParamSerializer({code: $scope.picCode})
            }).then(function successCallback(response) {
                console.log(response.data);
                $scope.username = response.data.username;
            }, function errorCallback(response) {
                console.log(response.data);
            });
        }
    });
</script>

</body>
</html>

Tutoriel recommandé : "TP5"

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer