Bonjour,

Je suis en train de développer une application, et étant encore nouvelle sur AngularJS je reçois cette erreur : RequestOptions is not defined..
J'ai cherché sur internet et j'ai vu qu'il fallait importer "RequestOptions". Mais n'étant pas encore familère avec l'environnement de anularjs je ne sais pas trop où je dois ajouter mon "import"

Quelqu'un pourrait m'éclairer s'il vous plait ?

Merci :)

16 réponses


MegLy
Auteur
Réponse acceptée

J'ai trouvé grace à ta piste lorsque tu as dis : "Cela dit, regarde si tu ne dois pas autoriser le header "Authorization" dans la liste des headers acceptés par le serveur" ;)
il fallait rajouter ça dans la conf de apache :
SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0

Solution trouvée ici : http://stackoverflow.com/questions/17018586/apache-2-4-php-fpm-and-authorization-headers/17490827

Bonjour,

Pourrais tu envoyer le bout de code qui te génères cette erreur ?
De plus tu es sur Angular et pas AngularJS non ? ( Il me semble que tu sois sur Angular 2 vu la classe que tu dois importer)

Angular => c'est la nouvelle version 2 ou 4
AngularJS => c'est la version 1.XX

MegLy
Auteur

Merci pour ta réponse,

Le bout de code qui génère cette erreur est le suivant :

    let headers = new Headers();
    headers.append('Authorization', 'Bearer ' + montoken);

    let options = new RequestOptions({ headers: headers }); // au niveau de cette ligne

    this.http.get('monurl', options)

Merci pour ces quelques précisions à propos de Angular

Salut,

Ton code se situe dans un controller ? Pourrais-tu nous montrer le code dans son entièreté ? Car là comme ça on va avoir du mal à t'aider.
De plus, je n'ai jamais entendu parler d'une classe RequestOptions.
Tu cherches à faire quoi exactement ? Par quel env passes-tu ?

MegLy
Auteur

Mon code se situe dans un service. En fait, j'ai utilisé ce code au départ :

var list = function(){
    var montoken = window.localStorage.getItem('token');
    return $http({
            method  : 'GET',
            url     : apiEndpoint.url + '/list',
            withCredentials : true,
            headers : {Authorization : 'Bearer ' + montoken}
        }).then(function(res) {
        console.log(res.data);
    });
}; 

Mais le soucis est que ce code me retourne l'erreur "401 unauthorized" et m'éjecte de l'application.
Pourtant lorsque je teste le token sur Postman, la requete GET vers l'url me retourne bien la liste à laquelle je cherche à accéder.
Du coup après toute la journée d'hier à chercher, on m'a conseillé d'utiliser RequestOptions, malheureusement je viens de découvrir ce matin qu'il faut l'importer via un TypeScript (chose que je n'ai pas encore faites jusqu'ici).

Attend là je comprend pas, tu utilises Angular ou AngularJS ? Car dans tes 2 codes que tu envois une fois et c'est Angular (2) et ensuite c'est du AngularJS.

Ensuite pour la 401 regarde avec le debugger les requests headers qui sont envoyé lors de la requête.

Peux tu nous envoyer ton full code pour la requête stp.

MegLy
Auteur

Bonsoir, excusez moi du retard, j'ai rencontré quelques soucis de connexion. Alors en effet je ne suis pas sous Angular 2, je me suis rendu compte de mon erreur.
Du coup j'ai apporté les quelques modifications à mon code pour essayer de résoudre mon problème, mais sans effet, toujours une erreur 401, alors que sur postman la requête fonctionne (ce qui me rassure d'un coté car cela signifie que le serveur n'est pas le problème)

Mon service.js :

angular.module('app.services', [])

.factory('BlankFactory', [function(){

}])

.service('LoginService', function($http, $rootScope, $ionicLoading, $ionicPopup, API_ENDPOINT){
    var LOCAL_TOKEN_KEY = 'yourTokenKey';
    var isAuthenticated = false;
    var authToken;

    function loadUserCredentials() {
        var token = window.localStorage.getItem(LOCAL_TOKEN_KEY);
        if (token) {
          useCredentials(token);
        }
    }

    function storeUserCredentials(token) {
        window.localStorage.setItem(LOCAL_TOKEN_KEY, token);
        useCredentials(token);
    }

    function useCredentials(token) {
        isAuthenticated = true;
        authToken = token;

        // Set the token as header for your requests!
        $http.defaults.headers.common.Authorization = authToken;
    }

    function destroyUserCredentials() {
        authToken = undefined;
        isAuthenticated = false;
        $http.defaults.headers.common.Authorization = undefined;
        window.localStorage.removeItem(LOCAL_TOKEN_KEY);
    }

    var login = function($mail, $password) {

            console.dir($rootScope);

            var data = {
                    mail: $mail,
                    password: $password
                };

            $ionicLoading.show();

            return $http(
                {
                    method  : 'POST',
                    url     : API_ENDPOINT.url + '/authenticate',
                    headers : {'Content-Type': 'application/x-www-form-urlencoded'},
                    transformRequest: function(obj) {
                        var str = [];
                        for(var p in obj)
                        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
                        return str.join("&");
                    },
                    data    : data
                })
                .then(function(response) {
                    var resp = response.data;
                    var status = response.status;
                    console.log("Code Status :", status);
                    if(status == 200) {
                        $rootScope.token = response.data.token;
                        window.localStorage.setItem('token', response.data.token);
                        storeUserCredentials($rootScope.token);
                        $rootScope.errorMessage = null;
                    } /*else {$rootScope.errorMessage = response.message;}*/
                    $ionicLoading.hide();
                }, function errorCallback(response) {
                    $ionicLoading.hide();
                    console.log(response);
                    var alertPopup = $ionicPopup.alert({
                    title: 'ERROR !',
                    template: 'Please check your creditentials'
                });
            });
        }

    var logout = function() {
        destroyUserCredentials();
    };

    var user = function(){
    return $http({
               method  : 'GET',
               url     : API_ENDPOINT.url + '/list'
           }).then(function(result) {
           console.log(result.data);
        });
    };

    loadUserCredentials();

    return {
        login : login,
        logout : logout,
        user : user,
        isAuthenticated: function() {return isAuthenticated;}
    }
})

.factory('AuthInterceptor', function ($rootScope, $q, AUTH_EVENTS) {
    var request = function(config) {
        config.headers = config.headers || {};
        var token = window.localStorage.getItem('token');
        if (config.headers) {
            config.headers.Authorization = 'Bearer ' + token;
        }
        return config || $q.when(config);
    };
    var responseError = function (response) {
        $rootScope.$broadcast({
        401: AUTH_EVENTS.notAuthenticated
      }[response.status], response);
        return $q.reject(response);
    };

  return {
        request : request,
        responseError: responseError
    };
})

.config(function ($httpProvider) {
  $httpProvider.defaults.withCredentials = true;
  $httpProvider.interceptors.push('AuthInterceptor')
});

Je tacherai de répondre dans les plus brefs délais à chaque fois, merci encore :)

Donc si tu n'as pas besoin d'importer RequestOptions, à quel endroit est-ce que cela coince du coup ? Au niveau de ta requête AJAX ?

MegLy
Auteur

ça coince à ce niveau là :

var user = function(){
    return $http({
               method  : 'GET',
               url     : API_ENDPOINT.url + '/list'
           }).then(function(result) {
           console.log(result.data);
        });
    };

Je reçois toujours une erreur "401 unauthorized", j'ai vérifié mon token et tout le reste mais rien n'y fais c'est comme si le serveur n'arrivait pas à recevoir mon token..

As-tu regardé dans ta console, onglet Network, dans les headers de ta requête, si le token est bien envoyé ?

MegLy
Auteur

oui, le token est bien dans les headers de la requete :
Request Header
Accept:application/json, text/plain, /
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Authorization:Bearer eyJhbGciOiJSUzI1NiJ9.......rAys0YkLvRCzgwfQegUmuqi-roaCx7O-oUcmGOrv3vWXE
Cache-Control:no-cache
Connection:keep-alive
Cookie:PHPSESSID=ravmf75pu5f6et5ergh5ld2c94
Host:localhost
Pragma:no-cache
Referer:http://localhost/Myapp/src/
User-Agent:Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Mobile Safari/537.36

Response Header
Cache-Control:no-cache
Connection:Keep-Alive
Content-Length:22
Content-Type:application/json
Date:Wed, 29 Mar 2017 09:24:40 GMT
Keep-Alive:timeout=5, max=98
Server:Apache/2.4.9 (Win64) PHP/5.5.12
X-Debug-Token:59c552
X-Debug-Token-Link:http://localhost/ws/web/app_dev.php/_profiler/59c552
X-Powered-By:PHP/5.5.12

General
Request URL:http://localhost/ws/web/app_dev.php/api/list
Request Method:GET
Status Code:401 Unauthorized
Remote Address:[::1]:80
Referrer Policy:no-referrer-when-downgrade

Et côté serveur ça donne quoi ? C'est une API PHP ? NodJS ? Rails ? Python ? Java ? Autre ? ^^
Comment récupère-tu ton token ? Est-ce que tu as bien autorisé le header justement ?

MegLy
Auteur

Coté serveur j'utilise une API PHP, Symfony ^^
Et de ce coté j'utilise ceci :

<?php

namespace AppBundle\Security;

use Doctrine\ORM\EntityManager;
use Lexik\Bundle\JWTAuthenticationBundle\Encoder\DefaultEncoder;
use Lexik\Bundle\JWTAuthenticationBundle\Encoder\JWTEncoder;
use Lexik\Bundle\JWTAuthenticationBundle\TokenExtractor\AuthorizationHeaderTokenExtractor;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;

class JwtAuthenticator extends AbstractGuardAuthenticator
{
    private $em;
    private $jwtEncoder;

    public function __construct(EntityManager $em, $jwtEncoder)
    {
        $this->em = $em;
        $this->jwtEncoder = $jwtEncoder;
    }

    public function start(Request $request, AuthenticationException $authException = null)
    {
        return new JsonResponse('Authorization header required', 401);
    }

    public function getCredentials(Request $request)
    {

        if(!$request->headers->has('Authorization')) {
            return;
        }

        $extractor = new AuthorizationHeaderTokenExtractor(
            'Bearer',
            'Authorization'
        );

        $token = $extractor->extract($request);

        if(!$token) {
            return;
        }

        return $token;
    }

    public function getUser($credentials, UserProviderInterface $userProvider)
    {
        $data = $this->jwtEncoder->decode($credentials);

        if(!$data){
            return;
        }

        $username = $data['mail'];

        $user = $this->em->getRepository('AppBundle:User')
            ->findOneBy(['mail' => $username]);

        if(!$user){
            return;
        }

        $role = $this->em->getRepository('AppBundle:User')->getAdmin($user->getId());
        $user->setRoles($role['maxAdmin']);

        return $user;
    }

    public function checkCredentials($credentials, UserInterface $user)
    {
        return true;
    }

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
    {
        return new JsonResponse([
            'message' => $exception->getMessage()
        ], 401);
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
    {
        return;
    }

    public function supportsRememberMe()
    {
        return false;
    }

}

Arf, je ne vais pas pouvoir t'aider plus que cela malheureusement, je ne connais pas assez (voire pas du tout) Symfony :/
Cela dit, regarde si tu ne dois pas autoriser le header "Authorization" dans la liste des headers acceptés par le serveur.
Jette un oeil à cette issue : https://github.com/FriendsOfSymfony/FOSRestBundle/issues/434#issuecomment-16333841 tu pourras peut-être t'en inspirer ;)

MegLy
Auteur

Ah dommage ^^' je vais voir du coté de cette piste en effet :)
merci d'avoir pris le temps de me lire tout de même

Pas de quoi, content que tu aies pu trouver ce que tu cherchais :)