Com a crescente popularidade de aplicativos de página única, aplicativos móveis e serviços RESTful API, o caminho desenvolvedores web o código de back-end de gravação mudou significativamente. Com tecnologias como AngularJS e BackboneJS, não estamos mais gastando muito tempo construindo marcação, em vez disso, estamos construindo APIs que nossos aplicativos de front-end consomem. Nosso back-end é mais sobre lógica de negócios e dados, enquanto a lógica de apresentação é movida exclusivamente para o front-end ou aplicativos móveis. Essas mudanças levaram a novas maneiras de implementar a autenticação em aplicativos modernos.
A autenticação é uma das partes mais importantes de qualquer aplicativo da web. Por décadas, cookies e autenticação baseada em servidor foram a solução mais fácil. No entanto, lidar com a autenticação em aplicativos móveis e de página única modernos pode ser complicado e exigir uma abordagem melhor. As soluções mais conhecidas para problemas de autenticação de APIs são as OAuth 2.0 e a JSON Web Token (JWT).
Antes de entrarmos neste tutorial do JSON Web Token, o que exatamente é um JWT?
Um JSON Web Token é usado para enviar informações que podem ser verificadas e confiáveis por meio de uma assinatura digital. Ele compreende um objeto JSON compacto e seguro para URL, que é assinado criptograficamente para verificar sua autenticidade e que também pode ser criptografado se a carga útil contiver informações confidenciais.
Devido à sua estrutura compacta, o JWT geralmente é usado em HTTP Authorization
cabeçalhos ou parâmetros de consulta de URL.
Um JWT é representado como uma sequência de base64url valores codificados que são separados por caracteres de ponto.
Aqui está um exemplo de token JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJpc3MiOiJ0b3B0YWwuY29tIiwiZXhwIjoxNDI2NDIwODAwLCJodHRwOi8vdG9wdGFsLmNvbS9qd3RfY2xhaW1zL2lzX2FkbWluIjp0cnVlLCJjb21wYW55IjoiVG9wdGFsIiwiYXdlc29tZSI6dHJ1ZX0. yRQYnWzskCZUxPwaQupWkiUzKELZ49eM7oWxAQK_ZXw
O cabeçalho contém os metadados do token e contém, no mínimo, o tipo de assinatura e o algoritmo de criptografia. (Você pode usar um Formatador JSON ferramenta para embelezar o objeto JSON.)
Cabeçalho de Exemplo
{ 'alg': 'HS256', 'typ': 'JWT' }
Este cabeçalho de exemplo JWT declara que o objeto codificado é um JSON Web Token e que é assinado usando o algoritmo HMAC SHA-256.
Uma vez que ele é codificado em base64, temos a primeira parte de nosso JWT.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
No contexto do JWT, uma declaração pode ser definida como uma declaração sobre uma entidade (normalmente, o usuário), bem como metadados adicionais sobre o próprio token. A declaração contém as informações que queremos transmitir e que o servidor pode usar para lidar com a autenticação JSON Web Token. Existem várias reivindicações que podemos fornecer; estes incluem nomes de reivindicações registradas, nomes de reivindicações públicas e nomes de reivindicações privadas.
Reclamações JWT registradas
Estas são as reivindicações que estão registradas no Registro de reivindicações de token da web JSON da IANA . Essas declarações JWT não pretendem ser obrigatórias, mas sim fornecer um ponto de partida para um conjunto de declarações úteis e interoperáveis.
Esses incluem:
Reivindicações públicas
As reivindicações públicas precisam ter nomes resistentes a colisões. Ao tornar o nome um URI ou URN, as colisões de nomenclatura são evitadas para JWTs onde o emissor e o receptor não fazem parte de uma rede fechada.
Um exemplo de um nome de reclamação público poderia ser: https://www.toptal.com/jwt_claims/is_admin
, e a prática recomendada é colocar um arquivo nesse local descrevendo a reclamação para que possa ser desreferenciada para documentação.
Reivindicações privadas
Nomes de declarações privados podem ser usados em locais onde os JWTs são trocados apenas em um ambiente fechado entre sistemas conhecidos, como dentro de uma empresa. Essas são afirmações que podemos definir a nós mesmos, como IDs de usuário, funções de usuário ou qualquer outra informação.
O uso de nomes de declaração que podem ter significados semânticos conflitantes fora de um sistema fechado ou privado está sujeito a colisão, portanto, use-os com cuidado.
É importante observar que queremos manter um token da web o menor possível, portanto, use apenas os dados necessários dentro de declarações públicas e privadas.
Exemplo de carga útil de JWT
{ 'iss': 'toptal.com', 'exp': 1426420800, 'https://www.toptal.com/jwt_claims/is_admin': true, 'company': 'ApeeScape', 'awesome': true }
Este exemplo de carga útil tem duas reivindicações registradas, uma pública e duas privadas. Uma vez codificado em base64, temos a segunda parte de nosso JWT.
eyJpc3MiOiJ0b3B0YWwuY29tIiwiZXhwIjoxNDI2NDIwODAwLCJodHRwOi8vdG9wdGFsLmNvbS9qd3RfY2xhaW1zL2lzX2FkbWluIjp0cnVlLCJjb21wYW55IjoiVG9wdGFsIiwiYXdlc29tZSI6dHJ1ZX0
O padrão JWT segue a especificação JSON Web Signature (JWS) para gerar o token final assinado. Ele é gerado combinando o cabeçalho JWT codificado e a carga útil JWT codificada, e assinando-o usando um algoritmo de criptografia forte, como HMAC SHA-256. A chave secreta da assinatura é mantida pelo servidor para que ele possa verificar os tokens existentes e assinar novos.
$encodedContent = base64UrlEncode(header) + '.' + base64UrlEncode(payload); $signature = hashHmacSHA256($encodedContent);
Isso nos dá a parte final de nosso JWT.
yRQYnWzskCZUxPwaQupWkiUzKELZ49eM7oWxAQK_ZXw
É fundamental usar TLS / SSL em conjunto com JWT, para evitar ataques man-in-the-middle. Na maioria dos casos, isso será suficiente para criptografar a carga útil do JWT se ela contiver informações confidenciais. No entanto, se quisermos adicionar uma camada adicional de proteção, podemos criptografar a carga útil do JWT usando o JSON Web Encryption Especificação (PLAY).
Claro, se quisermos evitar a sobrecarga adicional de usar o JWE, outra opção é simplesmente manter as informações confidenciais em nosso banco de dados e usar nosso token para chamadas de API adicionais para o servidor sempre que precisarmos acessar dados confidenciais.
Antes de podermos ver todos os benefícios do uso da autenticação JWT, temos que examinar a forma como a autenticação era feita no passado.
Como o protocolo HTTP não tem estado, deve haver um mecanismo para armazenar informações do usuário e uma maneira de autenticar o usuário em cada solicitação subsequente após o login. A maioria dos sites usa cookies para armazenar o ID da sessão do usuário.
Como funciona
O navegador faz uma solicitação POST ao servidor que contém a identificação e a senha do usuário. O servidor responde com um cookie, que é definido no navegador do usuário e inclui um ID de sessão para identificar o usuário.
Em cada solicitação subsequente, o servidor precisa encontrar essa sessão e desserializá-la, porque os dados do usuário são armazenados no servidor.
Difícil de escalar : O servidor precisa criar uma sessão para um usuário e mantê-la em algum lugar do servidor. Isso pode ser feito na memória ou em um banco de dados. Se tivermos um sistema distribuído, temos que nos certificar de que usamos um armazenamento de sessão separado que não está acoplado ao servidor de aplicativos.
Compartilhamento de solicitação de origem cruzada (CORS) : Ao usar chamadas AJAX para buscar um recurso de outro domínio ('origem cruzada'), podemos ter problemas com solicitações proibidas porque, por padrão, as solicitações HTTP não incluem cookies em solicitações de origem cruzada.
Acoplamento com a estrutura da web : Ao usar a autenticação baseada em servidor, estamos vinculados ao esquema de autenticação de nossa estrutura. É realmente difícil, ou mesmo impossível, compartilhar dados de sessão entre diferentes estruturas da web escritas em diferentes linguagens de programação.
A autenticação baseada em token / JWT não tem estado, portanto, não há necessidade de armazenar informações do usuário na sessão. Isso nos dá a capacidade de dimensionar nosso aplicativo sem nos preocupar onde o usuário está conectado. Podemos facilmente usar o mesmo token para buscar um recurso seguro de um domínio diferente daquele em que estamos conectados.
Como funcionam os tokens da web JSON
Um navegador ou cliente móvel faz uma solicitação ao servidor de autenticação contendo informações de login do usuário. O servidor de autenticação gera um novo token de acesso JWT e o retorna ao cliente. Em cada solicitação a um recurso restrito, o cliente envia o token de acesso na string de consulta ou Authorization
cabeçalho. O servidor então valida o token e, se for válido, retorna o recurso seguro para o cliente.
O servidor de autenticação pode assinar o token usando qualquer método de assinatura seguro. Por exemplo, um algoritmo de chave simétrica como HMAC SHA-256 pode ser usado se houver um canal seguro para compartilhar a chave secreta entre todas as partes. Como alternativa, um sistema de chave pública assimétrico, como RSA, também pode ser usado, eliminando a necessidade de compartilhamento adicional de chaves.
Sem estado, mais fácil de escalar : O token contém todas as informações para identificar o usuário, eliminando a necessidade do estado da sessão. Se usarmos um balanceador de carga, podemos passar o usuário para qualquer servidor, em vez de ser vinculado ao mesmo servidor em que efetuamos login.
Reutilização : Podemos ter muitos servidores separados, executando em várias plataformas e domínios, reutilizando o mesmo token para autenticar o usuário. É fácil construir um aplicativo que compartilhe permissões com outro aplicativo.
Segurança JWT : Como não usamos cookies, não precisamos nos proteger contra ataques de falsificação de solicitação entre sites (CSRF). Devemos ainda criptografar nossos tokens usando JWE se tivermos que colocar qualquer informação sensível neles e transmitir nossos tokens por HTTPS para evitar ataques man-in-the-middle.
atuação : Não há pesquisa do lado do servidor para localizar e desserializar a sessão em cada solicitação. A única coisa que precisamos fazer é calcular o HMAC SHA-256 para validar o token e analisar seu conteúdo.
Neste tutorial JWT, vou demonstrar como implementar a autenticação básica usando JSON Web Tokens em duas tecnologias populares da web: Laravel 5 para o código de back-end e AngularJS para o exemplo de aplicativo de página única (SPA) de front-end. (Você pode encontrar a demonstração completa Aqui , e o código-fonte em este repositório GitHub para que você possa acompanhar o tutorial.)
Este exemplo de token JSON da web não usará nenhum tipo de criptografia para garantir a confidencialidade das informações transmitidas nas reivindicações. Na prática, geralmente isso está correto, porque o TLS / SSL criptografa a solicitação. No entanto, se o token vai conter informações confidenciais, como o número da previdência social do usuário, ele também deve ser criptografado usando JWE.
Usaremos o Laravel para lidar com o registro do usuário, persistindo os dados do usuário em um banco de dados e fornecendo alguns dados restritos que precisam de autenticação para o aplicativo Angular consumir. Criaremos um subdomínio de API de exemplo para simular também o compartilhamento de recursos entre origens (CORS).
Instalação e inicialização do projeto
Para usar o Laravel, temos que instalar o Compositor gerenciador de pacotes em nossa máquina. Ao desenvolver no Laravel eu recomendo usar a “caixa” pré-embalada do Laravel Homestead do Vagrant. Ele nos fornece um ambiente de desenvolvimento completo, independentemente do nosso sistema operacional.
A maneira mais fácil de inicializar nosso aplicativo JWT Laravel é usar um instalador do Laravel do pacote Composer.
composer global require 'laravel/installer=~1.1'
Agora estamos todos prontos para criar um novo projeto Laravel executando laravel new jwt
.
Para qualquer dúvida sobre este processo, consulte o oficial Documentação do Laravel .
Depois de criar o aplicativo básico do Laravel 5, precisamos configurar nosso Homestead.yaml
, que irá configurar os mapeamentos de pastas e configurações de domínios para nosso ambiente local.
Exemplo de um Homestead.yaml
Arquivo:
--- ip: '192.168.10.10' memory: 2048 cpus: 1 authorize: /Users/ttkalec/.ssh/public.psk keys: - /Users/ttkalec/.ssh/private.ppk folders: - map: /coding/jwt to: /home/vagrant/coding/jwt sites: - map: jwt.dev to: /home/vagrant/coding/jwt/public - map: api.jwt.dev to: /home/vagrant/coding/jwt/public variables: - key: APP_ENV value: local
Depois de inicializarmos nossa caixa Vagrant com o vagrant up
e logado nele usando vagrant ssh
, navegamos para o diretório do projeto definido anteriormente. No exemplo acima, seria /home/vagrant/coding/jwt
. Agora podemos executar php artisan migrate
comando para criar as tabelas de usuário necessárias em nosso banco de dados.
Instalando Dependências do Composer
Felizmente, há uma comunidade de desenvolvedores trabalhando no Laravel e mantendo muitos pacotes excelentes com os quais podemos reutilizar e estender nossa aplicação. Neste exemplo, usaremos tymon/jwt-auth
, por Sean Tymon, para lidar com tokens no lado do servidor, e barryvdh/laravel-cors
, por Barry vd. Heuvel, para lidar com CORS.
jwt-auth
Requer o tymon/jwt-auth
pacote em nosso composer.json
e atualizar nossas dependências.
composer require tymon/jwt-auth 0.5.*
Adicione o JWTAuthServiceProvider
para o nosso app/config/app.php
matriz de provedores.
'TymonJWTAuthProvidersJWTAuthServiceProvider'
Em seguida, em app/config/app.php
, sob o aliases
, adicionamos o JWTAuth
fachada.
'JWTAuth' => 'TymonJWTAuthFacadesJWTAuth'
Finalmente, queremos publicar a configuração do pacote usando o seguinte comando: php artisan config: publish tymon / jwt-auth
Os tokens JSON da Web são criptografados usando uma chave secreta. Podemos gerar essa chave usando php artisan jwt:generate
comando. Ele será colocado dentro de nosso config/jwt.php
Arquivo. No ambiente de produção, no entanto, nunca queremos ter nossas senhas ou chaves de API dentro dos arquivos de configuração. Em vez disso, devemos colocá-los dentro das variáveis de ambiente do servidor e referenciá-los no arquivo de configuração com env
função. Por exemplo:
'secret' => env('JWT_SECRET')
Podemos descobrir mais sobre este pacote e todas as suas configurações no Github .
laravel-cors
Requer o barryvdh/laravel-cors
pacote em nosso composer.json
e atualizar nossas dependências.
composer require barryvdh/laravel-cors [email protected]
Adicione o CorsServiceProvider
para o nosso app/config/app.php
matriz de provedores.
'BarryvdhCorsCorsServiceProvider'
Em seguida, adicione o middleware ao nosso app/Http/Kernel.php
.
'BarryvdhCorsMiddlewareHandleCors'
Publique a configuração em um local config/cors.php
usando php artisan vendor:publish
comando.
Exemplo de um cors.php
configuração do arquivo:
return [ 'defaults' => [ 'supportsCredentials' => false, 'allowedOrigins' => [], 'allowedHeaders' => [], 'allowedMethods' => [], 'exposedHeaders' => [], 'maxAge' => 0, 'hosts' => [], ], 'paths' => [ 'v1/*' => [ 'allowedOrigins' => ['*'], 'allowedHeaders' => ['*'], 'allowedMethods' => ['*'], 'maxAge' => 3600, ], ], ];
Roteamento e tratamento de solicitações HTTP
Por uma questão de brevidade, colocarei todo o meu código dentro do arquivo routes.php que é responsável pelo roteamento do Laravel e delegação de requisições aos controladores. Normalmente criaríamos controladores dedicados para lidar com todas as nossas solicitações HTTP e manter nosso código modular e limpo.
Carregaremos nossa visualização do AngularJS SPA usando
Route::get('/', function () { return view('spa'); });
Registro do usuário
Quando fazemos um POST
solicitação para /signup
com um nome de usuário e senha, tentaremos criar um novo usuário e salvá-lo no banco de dados. Após a criação do usuário, um JWT é criado e retornado por meio da resposta JSON.
Route::post('/signup', function () { $credentials = Input::only('email', 'password'); try { $user = User::create($credentials); } catch (Exception $e) { return Response::json(['error' => 'User already exists.'], HttpResponse::HTTP_CONFLICT); } $token = JWTAuth::fromUser($user); return Response::json(compact('token')); });
Login do usuário
Quando fazemos um POST
solicitação para /signin
com um nome de usuário e senha, verificamos se o usuário existe e retorna um JWT por meio da resposta JSON.
Route::post('/signin', function () { $credentials = Input::only('email', 'password'); if ( ! $token = JWTAuth::attempt($credentials)) { return Response::json(false, HttpResponse::HTTP_UNAUTHORIZED); } return Response::json(compact('token')); });
Buscando um recurso restrito no mesmo domínio
Depois que o usuário estiver conectado, podemos buscar o recurso restrito. Eu criei uma rota /restricted
que simula um recurso que precisa de um usuário autenticado. Para fazer isso, a solicitação Authorization
o cabeçalho ou a string de consulta precisa fornecer o JWT para o back-end verificar.
Route::get('/restricted', [ 'before' => 'jwt-auth', function () { $token = JWTAuth::getToken(); $user = JWTAuth::toUser($token); return Response::json([ 'data' => [ 'email' => $user->email, 'registered_at' => $user->created_at->toDateTimeString() ] ]); } ]);
Neste exemplo, estou usando o jwt-auth
middleware fornecido no jwt-auth
pacote usando 'before' => 'jwt-auth'
. Esse middleware é usado para filtrar a solicitação e validar o token JWT. Se o token for inválido, ausente ou expirado, o middleware lançará uma exceção que podemos detectar.
No Laravel 5, podemos capturar exceções usando o app/Exceptions/Handler.php
Arquivo. Usando o render
função, podemos criar respostas HTTP com base na exceção lançada.
public function render($request, Exception $e) { if ($e instanceof TymonJWTAuthExceptionsTokenInvalidException) { return response(['Token is invalid'], 401); } if ($e instanceof TymonJWTAuthExceptionsTokenExpiredException) { return response(['Token has expired'], 401); } return parent::render($request, $e); }
Se o usuário for autenticado e o token for válido, podemos retornar com segurança os dados restritos para o front-end via JSON.
Buscar recursos restritos do subdomínio da API
No próximo exemplo de token da web JSON, usaremos uma abordagem diferente para validação de token. Em vez de usar jwt-auth
middleware, trataremos as exceções manualmente. Quando fazemos um POST
solicitação a um servidor API api.jwt.dev/v1/restricted
, estamos fazendo uma solicitação de origem cruzada e temos que habilitar o CORS no back-end. Felizmente, já configuramos o CORS no config/cors.php
Arquivo.
Route::group(['domain' => 'api.jwt.dev', 'prefix' => 'v1'], function () { Route::get('/restricted', function () { try { JWTAuth::parseToken()->toUser(); } catch (Exception $e) { return Response::json(['error' => $e->getMessage()], HttpResponse::HTTP_UNAUTHORIZED); } return ['data' => 'This has come from a dedicated API subdomain with restricted access.']; }); });
Estamos usando AngularJS como front-end, contando com as chamadas API para o servidor de autenticação back-end do Laravel para autenticação do usuário e dados de amostra, além do servidor API para dados de exemplo de origem cruzada. Assim que formos para a página inicial do nosso projeto, o back-end atenderá ao resources/views/spa.blade.php
visualização que inicializará o aplicativo Angular.
Esta é a estrutura de pastas do aplicativo Angular:
public/ |-- css/ `-- bootstrap.superhero.min.css |-- lib/ |-- loading-bar.css |-- loading-bar.js `-- ngStorage.js |-- partials/ |-- home.html |-- restricted.html |-- signin.html `-- signup.html `-- scripts/ |-- app.js |-- controllers.js `-- services.js
Bootstrapping o aplicativo angular
spa.blade.php
contém os fundamentos básicos necessários para executar o aplicativo. Usaremos o Twitter Bootstrap para estilização, junto com um tema personalizado de Bootswatch . Para ter algum feedback visual ao fazer uma chamada AJAX, usaremos o barra de carregamento angular script, que intercepta solicitações XHR e cria uma barra de carregamento. Na seção de cabeçalho, temos as seguintes folhas de estilo:
ngStorage
O rodapé de nossa marcação contém referências a bibliotecas, bem como nossos scripts personalizados para módulos, controladores e serviços Angular.
Authorization
Nós estamos usando token
biblioteca para AngularJS, para salvar tokens no armazenamento local do navegador, para que possamos enviá-lo em cada solicitação por meio do Toggle navigation JWT Angular example
cabeçalho.
No ambiente de produção, é claro, reduziríamos e combinaríamos todos os nossos arquivos de script e folhas de estilo para melhorar o desempenho.
Eu criei uma barra de navegação usando o Bootstrap que mudará a visibilidade dos links apropriados, dependendo do status de login do usuário. O status de entrada é determinado pela presença de um app.js
variável no escopo do controlador.
angular.module('app', [ 'ngStorage', 'ngRoute', 'angular-loading-bar' ]) .constant('urls', { BASE: 'http://jwt.dev:8000', BASE_API: 'http://api.jwt.dev:8000/v1' }) .config(['$routeProvider', '$httpProvider', function ($routeProvider, $httpProvider) { $routeProvider. when('/', { templateUrl: 'partials/home.html', controller: 'HomeController' }). when('/signin', { templateUrl: 'partials/signin.html', controller: 'HomeController' }). when('/signup', { templateUrl: 'partials/signup.html', controller: 'HomeController' }). when('/restricted', { templateUrl: 'partials/restricted.html', controller: 'RestrictedController' }). otherwise({ redirectTo: '/' });
Encaminhamento
Temos um arquivo chamado HomeController
que é responsável por configurar todas as nossas rotas de front end.
RestrictedController
Aqui podemos ver que definimos quatro rotas que são tratadas por Authorization
ou $httpProvider.interceptors.push(['$q', '$location', '$localStorage', function ($q, $location, $localStorage) { return { 'request': function (config) { config.headers = config.headers || {}; if ($localStorage.token) { config.headers.Authorization = 'Bearer ' + $localStorage.token; } return config; }, 'responseError': function (response) { if (response.status === 401 || response.status === 403) { $location.path('/signin'); } return $q.reject(response); } }; }]);
. Cada rota corresponde a uma visão HTML parcial. Também definimos duas constantes que contêm URLs para nossas solicitações HTTP para o backend.
Solicitar Interceptador
O serviço $ http do AngularJS permite que nos comuniquemos com o backend e façamos solicitações HTTP. Em nosso caso, queremos interceptar todas as solicitações HTTP e injetá-las com um controllers.js
cabeçalho contendo nosso JWT se o usuário for autenticado. Também podemos usar um interceptor para criar um manipulador de erros HTTP global. Aqui está um exemplo de nosso interceptor que injeta um token se estiver disponível no armazenamento local do navegador.
HomeController
Controladores
No RestrictedController
arquivo, definimos dois controladores para nossa aplicação: HomeController
e Auth
. angular.module('app') .controller('HomeController', ['$rootScope', '$scope', '$location', '$localStorage', 'Auth', function ($rootScope, $scope, $location, $localStorage, Auth) { function successAuth(res) { $localStorage.token = res.token; window.location = '/'; } $scope.signin = function () { var formData = { email: $scope.email, password: $scope.password }; Auth.signin(formData, successAuth, function () { $rootScope.error = 'Invalid credentials.'; }) }; $scope.signup = function () { var formData = { email: $scope.email, password: $scope.password }; Auth.signup(formData, successAuth, function () { $rootScope.error = 'Failed to signup'; }) }; $scope.logout = function () { Auth.logout(function () { window.location = '/' }); }; $scope.token = $localStorage.token; $scope.tokenClaims = Auth.getTokenClaims(); }])
lida com a funcionalidade de login, inscrição e logout. Ele passa os dados de nome de usuário e senha dos formulários de inscrição e inscrição para o RestrictedController
serviço, que envia solicitações HTTP para o back-end. Em seguida, ele salva o token no armazenamento local ou mostra uma mensagem de erro, dependendo da resposta do back-end.
getRestrictedData
getApiData
se comporta da mesma maneira, apenas busca os dados usando o Data
e .controller('RestrictedController', ['$rootScope', '$scope', 'Data', function ($rootScope, $scope, Data) { Data.getRestrictedData(function (res) { $scope.data = res.data; }, function () { $rootScope.error = 'Failed to fetch restricted content.'; }); Data.getApiData(function (res) { $scope.api = res.data; }, function () { $rootScope.error = 'Failed to fetch restricted API content.'; }); }]);
funções no Authorization
serviço.
tokenClaims
O back-end é responsável por servir os dados restritos apenas se o usuário for autenticado. Isso significa que, para responder com os dados restritos, a solicitação desses dados precisa conter um JWT válido dentro de seu getTokenClaims
cabeçalho ou string de consulta. Se esse não for o caso, o servidor responderá com um código de status de erro 401 Não autorizado.
Serviço de autenticação
O serviço Auth é responsável por fazer o login e inscrever solicitações HTTP para o back-end. Se a solicitação for bem-sucedida, a resposta conterá o token assinado, que é então decodificado em base64, e as informações de declarações de token incluídas são salvas em um angular.module('app') .factory('Auth', ['$http', '$localStorage', 'urls', function ($http, $localStorage, urls) { function urlBase64Decode(str) { var output = str.replace('-', '+').replace('_', '/'); switch (output.length % 4) { case 0: break; case 2: output += '=='; break; case 3: output += '='; break; default: throw 'Illegal base64url string!'; } return window.atob(output); } function getClaimsFromToken() { var token = $localStorage.token; var user = {}; if (typeof token !== 'undefined') { var encoded = token.split('.')[1]; user = JSON.parse(urlBase64Decode(encoded)); } return user; } var tokenClaims = getClaimsFromToken(); return { signup: function (data, success, error) { $http.post(urls.BASE + '/signup', data).success(success).error(error) }, signin: function (data, success, error) { $http.post(urls.BASE + '/signin', data).success(success).error(error) }, logout: function (success) { tokenClaims = {}; delete $localStorage.token; success(); }, getTokenClaims: function () { return tokenClaims; } }; } ]);
variável. Isso é passado para o controlador por meio do angular.module('app') .factory('Data', ['$http', 'urls', function ($http, urls) { return { getRestrictedData: function (success, error) { $http.get(urls.BASE + '/restricted').success(success).error(error) }, getApiData: function (success, error) { $http.get(urls.BASE_API + '/restricted').success(success).error(error) } }; } ]);
função.
|_+_|
Serviço de dados
Este é um serviço simples que faz solicitações ao servidor de autenticação e também ao servidor API para alguns dados restritos fictícios. Ele faz a solicitação e delega retornos de chamada de sucesso e erro ao controlador.
|_+_|
A autenticação baseada em token nos permite construir sistemas desacoplados que não estão vinculados a um esquema de autenticação específico. O token pode ser gerado em qualquer lugar e consumido em qualquer sistema que use a mesma chave secreta para assinar o token. Eles estão prontos para dispositivos móveis e não exigem o uso de cookies.
JSON Web Tokens funcionam em todas as linguagens de programação populares e estão ganhando popularidade rapidamente. Eles são apoiados por empresas como Google, Microsoft e Zendesk. Sua especificação padrão pela Internet Engineering Task Force (IETF) é ainda na versão de rascunho e pode mudar um pouco no futuro.
Ainda há muito a ser abordado sobre os JWTs, como lidar com os segurança detalhes e tokens atualizados quando eles expiram, mas o tutorial JSON Web Token deve demonstrar o uso básico e, mais importante, as vantagens de usar JWTs.
Isso se refere a um JWT, que é transmitido por meio do cabeçalho HTTP chamado Authorization, no formato de string 'Bearer $ your_token_here'.
JWT significa JSON Web Token, uma tática de autenticação comum usada em aplicativos da web modernos.
JSON é simplesmente um formato de dados que se parece muito com o formato literal de dados permitido por JavaScript. É um formato hierárquico que permite objetos e matrizes aninhados, bem como strings e literais de número.