Repository: codecasts/laravel-jwt
Branch: master
Commit: 3e26ca60041e
Files: 19
Total size: 51.4 KB
Directory structure:
gitextract_u6zs6ejr/
├── .github/
│ └── workflows/
│ └── build.yml
├── .gitignore
├── .travis.yml
├── CONTRIBUTING.md
├── LICENSE.txt
├── composer.json
├── config/
│ └── jwt.php
├── phpunit.xml
├── readme.md
├── sonar-project.properties
├── src/
│ ├── Auth/
│ │ ├── Guard.php
│ │ └── ServiceProvider.php
│ ├── Console/
│ │ └── KeyGenerateCommand.php
│ ├── Contracts/
│ │ ├── Auth/
│ │ │ └── Guard.php
│ │ └── Token/
│ │ └── Manager.php
│ ├── ServiceProvider.php
│ └── Token/
│ └── Manager.php
└── tests/
├── Auth/
│ └── GuardTest.php
└── TestCase.php
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/build.yml
================================================
name: Build
on:
push:
branches:
- master
pull_request:
types: [opened, synchronize, reopened]
jobs:
sonarcloud:
name: SonarCloud
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
================================================
FILE: .gitignore
================================================
composer.lock
/vendor
================================================
FILE: .travis.yml
================================================
language: php
sudo: false
git:
depth: 2
matrix:
include:
- php: 7.0
- php: 7.1
- php: 7.2
- php: nightly
fast_finish: true
cache:
directories:
- $HOME/.composer/cache
before_script:
- phpenv config-rm xdebug.ini || true
- travis_retry composer self-update
- travis_retry composer install --no-interaction
script:
- composer test
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
Contributions are **welcome** and will be fully **credited**.
We accept contributions via Pull Requests on [Github](https://github.com/codecasts/laravel-jwt).
## Pull Requests
- Follow the **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)**.
- **Add tests!** - Your patch won't be accepted if it doesn't have tests.
- **Document any change in behaviour** - Make sure the `readme.md` and any other relevant documentation are kept up-to-date.
- **Consider our release cycle** - We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option.
- **Create feature branches** - Don't ask us to pull from your master branch.
- **One pull request per feature** - If you want to do more than one thing, send multiple pull requests.
- **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](http://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting.
- **Branch** - This is a **GIT FLOW** enabled repository, so please send your pull requests to our `develop` branch.
## Running Tests
``` bash
$ composer test
```
**Happy coding**!
================================================
FILE: LICENSE.txt
================================================
MIT License
Copyright (c) 2017 Diego Hernandes <diego@hernandev.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: composer.json
================================================
{
"name": "codecasts/laravel-jwt",
"description": "Dead simple JWT Auth Provider for Laravel 5.4+",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Diego Hernandes",
"email": "diego@hernandev.com"
}
],
"autoload": {
"psr-4": {
"Codecasts\\Auth\\JWT\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"minimum-stability": "stable",
"require": {
"php": ">=7.0.0",
"ext-openssl": "*",
"lcobucci/jwt": "^3.2",
"illuminate/support": ">=5.4.0"
},
"require-dev": {
"orchestra/testbench": "^3.4",
"phpunit/phpunit": "^6.1",
"mockery/mockery": "^0.9.9"
},
"extra": {
"laravel": {
"providers": [
"Codecasts\\Auth\\JWT\\ServiceProvider"
]
}
}
}
================================================
FILE: config/jwt.php
================================================
<?php
/*
|--------------------------------------------------------------------------
| GENERAL WARNING. DO NOT USE THIS PACKAGE WITHOUT READING THIS.
|--------------------------------------------------------------------------
|
| It's 2017. JWT are a (not so much) new and simple way of authenticating your
| users either you're building a SPA + API or Mobile + API app.
|
| It's great you took interest in this package, but you should take real care
| about the following things:
|
| As I was saying. It's 2017. JWT SHOULD NOT BE USED on a API WITHOUT HTTPS.
| By HTTP, I mean TLS 1.1+.
| SSL 3.0 and lower are proven insecure actually a couple of years ago.
|
| With that in mind, enjoy this. It was made with love with minimalism in mind.
*/
return [
/*
|--------------------------------------------------------------------------
| JWT Secret
|--------------------------------------------------------------------------
|
| This package uses HMAC-SHA265 as default signature mechanism.
| HMAC-256 is pretty secure and straightforward when using a 32 bytes long key.
| Since this package aims to be really simple, the crypt algorithm and key length
| will be hardcoded instead of configurable.
|
| This will be like this by design, it will provide strong security for any API
| while preventing people from making a mess and turning JWT less secure.
|
| NOTICE: ONLY USE KEYS GENERATED BY THE COMMAND
|
| php artisan jwt:generate
|
| If you don't, don't blame me latter.
|
| P.S. Don't blame me in any case :).
*/
'secret' => env('JWT_SECRET', null),
/*
|--------------------------------------------------------------------------
| JWT Time to live (TTL)
|--------------------------------------------------------------------------
|
| Use an Integer value in minutes.
|
| This will set how long will take for a key to be considered expired.
| In other words, this is the amount of time, in minutes, that will be
| added to the current time that the token is being issue and set
| ont the 'exp' claim.
|
*/
'ttl' => 60,
/*
|--------------------------------------------------------------------------
| Expired Token Refresh Limit
|--------------------------------------------------------------------------
|
| Use an Integer value in minutes.
|
| This will set how long after the expiration date a token can be refreshed.
| You can set it to 0 if you DO NOT want expired tokens to refreshed.
|
| The default limit of 7200 (minutes) takes in account mobile apps where the
| logged used may take a few days before using your "app" again.
|
| In those cases, the token would have been expired but a new one could still
| be issued, unless the limit configured here has already passed.
|
| If you're considering a not secure client platform, short values here reduces
| the odds of a leaked token be used to generate a new one.
|
*/
'refresh_limit' => 7200,
/*
|--------------------------------------------------------------------------
| Auto Guard Binding By Middleware Match
|--------------------------------------------------------------------------
|
| Useful when your application has more than 1 guard, and the JWT powered one
| is not the default.
|
| If your application is a API only, you can safely set this to false.
|
| Setting it to false without having JWT guard as default will make
| mandatory using the suffix :guardName when using the 'auth' middleware.
|
*/
'middleware_match' => true,
];
================================================
FILE: phpunit.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="true"
syntaxCheck="false">
<testsuites>
<testsuite name="LaravelJwt Test Suite">
<directory>tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
</phpunit>
================================================
FILE: readme.md
================================================

# Laravel JWT
[](https://packagist.org/packages/codecasts/laravel-jwt)
[](https://packagist.org/packages/codecasts/laravel-jwt)
[](https://packagist.org/packages/codecasts/laravel-jwt)
This package provides out-of-the-box API authentication using JWT for Laravel.
## Installation.
You can install this package by running:
```bash
composer require codecasts/laravel-jwt
```
## Setup.
In order to setup this package into your application, minimal configuration
is actually needed.
### 1) Service Provider.
Register this package's Service Provider by adding it to the `providers`
section of your `config/app.php` file:
> You may skip this step on Laravel 5.5 due to the [auto-discovery package feature](https://laravel.com/docs/5.5/packages#package-discovery).
```php
'providers' => [
// ... other providers omitted
Codecasts\Auth\JWT\ServiceProvider::class,
],
```
### 2) Configuration file.
Publish the configuration file (`config/jwt.php`) by running the
following command after registering the Service Provider.
```bash
php artisan vendor:publish --provider="Codecasts\Auth\JWT\ServiceProvider"
```
### 3) Generate a Secret.
In order for this package to works, you will need a separate secret
(do not use the application key).
This package provides a command that can be used for generating a strong key.
Get a new key by running:
```bash
php artisan jwt:generate
```
Then, copy the generated key contents into your `.env` file.
**NOTICE**: The key generation process will not automatically
set it inside your `.env` file, do it manually.
### 4) Setup Guard
In order to automatically authenticate your routes using `JWT` tokens,
you need to change the guard driver to `jwt`
Inside `config/auth.php` set the corresponding guard group you want to protect:
If you have the default guard group named `api`, your `auth.php`
should be like this:
```php
'guards' => [
// ... other guards omitted.
'api' => [
'driver' => 'jwt', // this is the line you need to change.
'provider' => 'users',
],
],
```
That's it, we are all ready to use it.
## Usage.
This package aims to be dead simple to use.
The following templates can be used to setup your existing
authentication controllers and resources.
**NOTICE**: Full working examples of use for this package
will be added on this package when it reaches it's 1.0 version.
### Protecting Routes.
This package is fully integrated with Laravel Authentication.
The default configuration (`config/jwt.php`) brings a sensitive value that
is very useful when your application is not completely an API: **`middleware_match`**
By not completely an API, I mean, the JWT guard is not the default one.
In those cases, in order to use the `auth` middleware, the config key
**`middleware_match`** **MUST** be set to true.
This configuration key allows non protected routes to work properly.
Notice that this option will match middleware group names with guard names.
**In this case, the 'api' middleware group will always use the `api` guard.**
**Also, the 'web' middleware group will always use the `web` guard**
If you do not use this value, you will need to use suffixes when referencing the
`auth` middleware, like `auth:api`.
### Issuing and Renewing Tokens.
For issuing tokens, no special class is actually needed,
you can just expect create a Guard current implementation from the IoC and work from there.
Check out the examples.
**On the following examples, all Guard instances are injected from `Illuminate\Contracts\Auth\Guard`**
**On the following examples, all Request instances are injected from `Illuminate\Http\Request`**
#### Token from User Instance.
This method should be used when you just registered a user and any other
special cases.
```php
public function tokenFromUser(Guard $auth)
{
// generating a token from a given user.
$user = SomeUserModel::find(12);
// logs in the user
$auth->login($user);
// get and return a new token
$token = $auth->issue();
return $token;
}
```
#### Token from User Credentials.
This method should be used when you just registered a user and any other
special cases.
```php
public function tokenFromCredentials(Guard $auth, Request $request)
{
// get some credentials
$credentials = $request->only(['email', 'password']);
if ($auth->attempt($credentials)) {
return $token = $auth->issue();
}
return ['Invalid Credentials'];
}
```
#### Refreshing Tokens.
Tokens can be refreshed in 2 different ways: Auto detect or manual.
If you do not pass any argument into the refresh method, the Guard will
look for either a **`Authorization`** header or a **`token`** field on the
request's body.
```php
public function refreshToken(Guard $auth)
{
// auto detecting token from request.
$token = $auth->refresh();
// manually passing the token to be refreshed.
$token = $auth->refresh($oldToken);
return $token;
}
```
### Custom Claims.
Of course, there are support for custom claims.
You can set them in two ways.
#### By explicitly passing them.
```php
$customClaims = [
'custom1' => 'value1',
'custom2' => 'value2',
];
// when issuing
$auth->issue($customClaims);
// when refreshing
// custom claims are the second parameter as the first one is the
// old token
$auth->refresh(null, $customClaims);
```
#### By Authenticatable method.
If all your users will have the same custom claims, you can setup a default
custom claims method on your User's model (or any other Authenticatable you're using):
If the method `customJWTClaims()` is present on the model being issue the token against,
this claims will be automatically included.
```php
class User extends Model implements Authenticatable
{
public function customJWTClaims()
{
return [
'email' => $this->email,
'name' => $this->name,
];
}
}
```
## Contributing
Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
================================================
FILE: sonar-project.properties
================================================
sonar.projectKey=codecasts_laravel-jwt
sonar.organization=codecasts
# This is the name and version displayed in the SonarCloud UI.
#sonar.projectName=laravel-jwt
#sonar.projectVersion=1.0
# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
#sonar.sources=.
# Encoding of the source code. Default is default system encoding
#sonar.sourceEncoding=UTF-8
================================================
FILE: src/Auth/Guard.php
================================================
<?php
namespace Codecasts\Auth\JWT\Auth;
use Illuminate\Auth\Events\Attempting;
use Illuminate\Auth\Events\Failed;
use Illuminate\Auth\Events\Login;
use Illuminate\Auth\GuardHelpers;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Events\Dispatcher;
use Symfony\Component\HttpFoundation\Request;
use Illuminate\Support\Str;
use Codecasts\Auth\JWT\Contracts\Auth\Guard as GuardContract;
use Lcobucci\JWT\Token;
/**
* JWT Guard class.
*
* This class is responsible for actually authenticating requests that
* comes with a token (or denying those without a token or with a
* invalid one).
*/
class Guard implements GuardContract
{
// this trait bootstrap some common guard methods
// so we just need to implement a few ones.
use GuardHelpers;
/**
* @var \Illuminate\Contracts\Foundation\Application
*/
protected $app;
/**
* Guard / Provider name.
*
* @var string
*/
protected $name;
/**
* The currently authenticated user.
*
* @var \Illuminate\Contracts\Auth\Authenticatable
*/
protected $user;
/**
* The user provider implementation.
*
* @var \Illuminate\Contracts\Auth\UserProvider
*/
protected $provider;
/**
* The token manager implementation.
*
* @var \Codecasts\Auth\JWT\Contracts\Token\Manager
*/
protected $manager;
/**
* Used to allow checks just after logout.
*
* In a JWT scenario, logged out means there was an explicit action
* to log out the user and the token has been blacklisted.
*
* @var bool
*/
protected $loggedOut = false;
/**
* The event dispatcher instance.
*
* @var \Illuminate\Contracts\Events\Dispatcher
*/
protected $events;
/**
* The current Request;
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $request;
/**
* The user we last attempted to retrieve.
*
* @var \Illuminate\Contracts\Auth\Authenticatable
*/
protected $lastAttempted;
/**
* The detected JWT token.
*
* @var Token|null
*/
protected $token = null;
/**
* JWT Guard constructor.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @param string $name
* @param \Illuminate\Contracts\Auth\UserProvider $provider
* @param \Codecasts\Auth\JWT\Contracts\Token\Manager $manager
*/
public function __construct($app, $name, $provider, $manager)
{
// assign constructor arguments into instance scope.
$this->app = $app;
$this->name = $name;
$this->provider = $provider;
$this->manager = $manager;
}
/**
* Fire the attempt event with the arguments.
*
* @param array $credentials
* @return void
*/
protected function fireAttemptEvent(array $credentials)
{
if (isset($this->events)) {
$this->events->dispatch(new Attempting(
$credentials, false
));
}
}
/**
* Fire the failed authentication attempt event with the given arguments.
*
* @param \Illuminate\Contracts\Auth\Authenticatable|null $user
* @param array $credentials
* @return void
*/
protected function fireFailedEvent($user, array $credentials)
{
if (isset($this->events)) {
$this->events->dispatch(new Failed($user, $credentials));
}
}
/**
* Fire the login event if the dispatcher is set.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
*
* @return void
*/
protected function fireLoginEvent($user)
{
if (isset($this->events)) {
$this->events->dispatch(new Login($user, false));
}
}
/**
* Validate a user's credentials.
*
* @param array $credentials
* @return bool
*/
public function validate(array $credentials = [])
{
$this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);
return $this->hasValidCredentials($user, $credentials);
}
/**
* Attempt to authenticate a user using the given credentials.
*
* @param array $credentials
* @return bool
*/
public function attempt(array $credentials = [])
{
$this->fireAttemptEvent($credentials);
$this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);
// If an implementation of UserInterface was returned, we'll ask the provider
// to validate the user against the given credentials, and if they are in
// fact valid we'll log the users into the application and return true.
if ($this->hasValidCredentials($user, $credentials)) {
$this->login($user);
return true;
}
// If the authentication attempt fails we will fire an event so that the user
// may be notified of any suspicious attempts to access their account from
// an unrecognized user. A developer may listen to this event as needed.
$this->fireFailedEvent($user, $credentials);
return false;
}
/**
* Determine if the user matches the credentials.
*
* @param mixed $user
* @param array $credentials
* @return bool
*/
protected function hasValidCredentials($user, $credentials)
{
return ! is_null($user) && $this->provider->validateCredentials($user, $credentials);
}
/**
* Login a given user. It means, generate a new token for a user.
*
* @param Authenticatable $user
* @return mixed
*/
public function login(Authenticatable $user)
{
// If we have an event dispatcher instance set we will fire an event so that
// any listeners will hook into the authentication events and run actions
// based on the login and logout events fired from the guard instances.
$this->fireLoginEvent($user);
$this->setUser($user);
}
/**
* Parse the request looking for the authorization header.
*
* @return null|string
*/
protected function getTokenFromHeader()
{
// if there is no authorization header present.
if (!$this->getRequest()->headers->has('Authorization')) {
// abort by returning null.
return null;
}
// gets the full header string.
$header = $this->getRequest()->headers->get('Authorization');
// returns the token without the 'Bearer ' prefix.
return Str::replaceFirst('Bearer ', '', $header);
}
/**
* Parse the request looking a token as parameter.
*
* @return null|string
*/
protected function getTokenFromParameter()
{
if (!$this->getRequest()->has('token')) {
// abort by returning null.
return null;
}
// return the request token.
return $this->getRequest()->get('token', null);
}
/**
* @return Token|null
*/
protected function detectedToken()
{
// retrieve the token from request.
$detectedToken = $this->getTokenFromHeader() ?? $this->getTokenFromParameter();
if ($detectedToken) {
// update the currently used token
$this->token = $this->manager()->parseToken($detectedToken);
}
// return current token in use
return $this->token;
}
/**
* Retrieves the user by it's token.
*
* @param Token $token
* @return Authenticatable|null
*/
protected function findUserByToken(Token $token)
{
// retrieves the user ID from the token.
$id = $token->getClaim('sub');
// use the users provider to find the token subject (user)
// but it's id (subject)
return $this->provider->retrieveById($id);
}
/**
* Get / Detect the currently authenticated user.
*
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function user()
{
// if the user was explicitly marked as logged out.
if ($this->loggedOut) {
// just return null.
return null;
}
// if the user is already set.
if ($this->user) {
return $this->user;
}
// detects a token presence.
$token = $this->detectedToken();
// if the received token is not actually valid.
if (!$token || !$this->manager->validToken($token)) {
// also return null since the token
// signature could not be determined.
return null;
}
// if the token has expired.
if ($this->manager->expired($token)) {
// you got right?
return null;
}
// try to find the user which the token belongs to.
$user = $this->findUserByToken($token);
// if the user has not been found.
if (!$user) {
// abort!
return null;
}
// set the current user on the scope.
$this->setUser($user);
// return the scope user.
return $this->user;
}
/**
* Log the user out of the application.
*
* @return void
*/
public function logout()
{
$user = $this->user();
// blacklist the user token.
$this->loggedOut = true;
}
/**
* Returns the guard instance of the token manager.
*
* @return \Codecasts\Auth\JWT\Contracts\Token\Manager
*/
public function manager()
{
return $this->manager;
}
/**
* Issue a token for the current authenticated user.
*
* @param array $customClaims
* @return bool|string
*/
public function issue(array $customClaims = [])
{
// ensure there is a user logged in.
if (!$this->user) {
return false;
}
// try to issue a new token and return.
try {
return $this->manager()->issue($this->user, $customClaims);
} catch (\Exception $e) {
// catch any exceptions that the token issuing may trigger.
return false;
}
}
/**
* Refresh a given token.
*
* @param string $token
* @param array $customClaims
* @return bool|string
*/
public function refresh(string $token = null, array $customClaims = [])
{
// detect token if none was passed.
$token = $token ?? $this->detectedToken();
// if no token was detected.
if (!$token) {
return false;
}
// if the token cannot be refreshed.
if (!$this->manager()->canBeRenewed($token)) {
// abort by returning false.
return false;
}
// try to locate the user which the token belongs to.
$user = $this->findUserByToken($token);
// if not user could be found.
if (!$user) {
return false;
}
// set the user instance.
$this->user = $user;
// try to issue a new token and refresh
try {
return $this->manager()->issue($user, $customClaims);
} catch (\Exception $e) {
return false;
}
}
/**
* Get the event dispatcher instance.
*
* @return \Illuminate\Contracts\Events\Dispatcher
*/
public function getDispatcher()
{
return $this->events;
}
/**
* Set the event dispatcher instance.
*
* @param \Illuminate\Contracts\Events\Dispatcher $events
* @return void
*/
public function setDispatcher(Dispatcher $events)
{
$this->events = $events;
}
/**
* Get the current request instance.
*
* @return \Symfony\Component\HttpFoundation\Request
*/
public function getRequest()
{
return $this->request ?: $this->app->request;
}
/**
* Set the current request instance.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @return $this
*/
public function setRequest(Request $request)
{
$this->request = $request;
return $this;
}
/**
* The detected JWT token.
*
* @return string
*/
public function getToken()
{
return $this->token;
}
}
================================================
FILE: src/Auth/ServiceProvider.php
================================================
<?php
namespace Codecasts\Auth\JWT\Auth;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider;
use Codecasts\Auth\JWT\Contracts\Token\Manager as TokenManager;
use Illuminate\Auth\AuthManager;
/**
* Service provider to register the 'jwt' auth guard.
*/
class ServiceProvider extends AuthServiceProvider
{
/**
* Laravel auth manager that will be needed to register the guard.
*
* @var AuthManager
*/
protected $authManager = null;
/**
* Register Guard.
*/
public function register()
{
// gets the auth factory instance and register on provider attribute.
$this->authManager = $this->app->make(AuthManager::class);
// register auth policies.
$this->registerPolicies();
// define a "jwt" guard.
$this->authManager->extend('jwt', function ($app, $name, array $config) {
// gets a instance of the token manager
$tokenManager = $this->getTokenManager();
// gets a instance of the user provider
$userProvider = $this->getUserProvider($config['provider']);
// creates a new guard instance passing a provider and a token manager
$guard = new Guard($app, $name, $userProvider, $tokenManager);
// set a event dispatcher on the guard.
$guard->setDispatcher(resolve(Dispatcher::class));
// returns the guard instance.
return new Guard($app, $name, $userProvider, $tokenManager);
});
}
/**
* Get's the configured user provider instance.
*
* @param $alias
* @return UserProvider
*/
protected function getUserProvider($alias)
{
return $this->authManager->createUserProvider($alias);
}
/**
* Get's a instance of the token manager.
*
* @return \Codecasts\Auth\JWT\Contracts\Token\Manager
*/
protected function getTokenManager()
{
return $this->app->make(TokenManager::class);
}
}
================================================
FILE: src/Console/KeyGenerateCommand.php
================================================
<?php
namespace Codecasts\Auth\JWT\Console;
use Illuminate\Console\Command;
use Illuminate\Console\ConfirmableTrait;
use Symfony\Component\Console\Helper\FormatterHelper;
/**
* Class GenerateKey.
*
* Command that helps generating a strong key to be used as HMAC-SHA256 key.
*/
class KeyGenerateCommand extends Command
{
use ConfirmableTrait;
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'jwt:generate
{--show : Display the key instead of modifying files}
{--force : Force the operation to run when in production}';
/**
* Make it 5.4 compatible.
*/
public function fire()
{
$this->handle();
}
/**
* Execute the command that will generate and print a key.
*/
public function handle()
{
// call the action to generate a new key.
$key = $this->generateRandomKey();
if ($this->option('show')) {
// print the success block.
$this->printBlock([
'JWT Key Generated!',
'Please Update your .env file manually with the following key:',
], 'bg=green;fg=black', true);
// print the key block.
return $this->printBlock([
"JWT_SECRET={$key}",
], 'bg=yellow;fg=black');
}
// Next, we will replace the application key in the environment file so it is
// automatically setup for this developer. This key gets generated using a
// secure random byte generator and is later base64 encoded for storage.
if (!$this->setKeyInEnvironmentFile($key)) {
return;
}
$this->laravel['config']['jwt.secret'] = $key;
// print the key block.
$this->printBlock([
"JWT_SECRET={$key}",
], 'bg=yellow;fg=black');
}
/**
* Set the application key in the environment file.
*
* @param string $key
*
* @return bool
*/
protected function setKeyInEnvironmentFile($key)
{
$currentKey = $this->laravel['config']['jwt.secret'];
if (0 !== strlen($currentKey) && (!$this->confirmToProceed())) {
return false;
}
$this->writeNewEnvironmentFileWith($key);
return true;
}
/**
* Write a new environment file with the given key.
*
* @param string $key
*/
protected function writeNewEnvironmentFileWith($key)
{
file_put_contents($this->laravel->environmentFilePath(), preg_replace(
$this->keyReplacementPattern(),
'JWT_SECRET='.$key,
file_get_contents($this->laravel->environmentFilePath())
));
}
/**
* Generates a random, 32 bytes long, base64 encoded key.
*
* @return string
*/
protected function generateRandomKey()
{
return 'base64:'.base64_encode(random_bytes(32));
}
/**
* Prints a text block into console output.
*
* @param array $lines
* @param $style
* @param bool $firstBlock
*/
protected function printBlock(array $lines, $style, $firstBlock = false)
{
/** @var FormatterHelper $formatter */
$formatter = $this->getHelper('formatter');
// just to satisfy my obsessive needs.
if ($firstBlock) {
// prints an empty line at the begging of output.
$this->line('');
}
// merge argument lines with an empty line before and after.
$spacedLines = array_merge([''], array_merge($lines, ['']));
// generate a text block.
$block = $formatter->formatBlock($spacedLines, $style);
// print it.
$this->line($block);
// empty ending line.
$this->line('');
}
/**
* Get a regex pattern that will match env APP_KEY with any random key.
*
* @return string
*/
protected function keyReplacementPattern()
{
$escaped = preg_quote('='.$this->laravel['config']['jwt.secret'], '/');
return "/^JWT_SECRET{$escaped}/m";
}
}
================================================
FILE: src/Contracts/Auth/Guard.php
================================================
<?php
namespace Codecasts\Auth\JWT\Contracts\Auth;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Guard as LaravelGuard;
use Illuminate\Contracts\Events\Dispatcher;
use Codecasts\Auth\JWT\Contracts\Token\Manager;
use Symfony\Component\HttpFoundation\Request;
interface Guard extends LaravelGuard
{
/**
* JWT Guard constructor.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @param string $name
* @param \Illuminate\Contracts\Auth\UserProvider $provider
* @param \Codecasts\Auth\JWT\Contracts\Token\Manager $manager
*/
public function __construct($app, $name, $provider, $manager);
/**
* @param array $credentials
* @return mixed
*/
public function validate(array $credentials = []);
/**
* Attempt to authenticate a user using the given credentials.
*
* @param array $credentials
* @return bool
*/
public function attempt(array $credentials = []);
/**
* Log a user into the application.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @return void
*/
public function login(Authenticatable $user);
/**
* Log the user out of the application.
*
* @return void
*/
public function logout();
/**
* Returns the guard instance of the token manager.
*
* @return Manager
*/
public function manager();
/**
* Refresh a given token.
*
* @param string $token
* @param array $customClaims
* @return bool|string
*/
public function refresh(string $token = null, array $customClaims = []);
/**
* Issue a token for the current authenticated user.
*
* @param array $customClaims
* @return bool|string
*/
public function issue(array $customClaims = []);
/**
* Get the event dispatcher instance.
*
* @return \Illuminate\Contracts\Events\Dispatcher
*/
public function getDispatcher();
/**
* Set the event dispatcher instance.
*
* @param \Illuminate\Contracts\Events\Dispatcher $events
* @return void
*/
public function setDispatcher(Dispatcher $events);
/**
* Get the current request instance.
*
* @return \Symfony\Component\HttpFoundation\Request
*/
public function getRequest();
/**
* Set the current request instance.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @return $this
*/
public function setRequest(Request $request);
}
================================================
FILE: src/Contracts/Token/Manager.php
================================================
<?php
namespace Codecasts\Auth\JWT\Contracts\Token;
use \Illuminate\Cache\Repository as Cache;
use \Illuminate\Config\Repository as Config;
use Illuminate\Contracts\Auth\Authenticatable;
use Lcobucci\JWT\Token;
interface Manager
{
/**
* Token Manager constructor.
*
* @param \Illuminate\Config\Repository $config
* @param \Illuminate\Cache\Repository $cache
*/
public function __construct(Config $config, Cache $cache);
/**
* Setup the secret that will be used to sign keys.
*/
public function setupSecret();
/**
* @param Authenticatable $user
* @param array $customClaims
*
* @return string
*/
public function issue(Authenticatable $user, array $customClaims = []);
/**
* Method for parsing a token from a string.
*
* @param string $tokenString
*
* @return Token
*/
public function parseToken(string $tokenString);
/**
* Detects if a given token is valid or not.
*
* @param Token $token
*
* @return bool
*/
public function validToken(Token $token);
/**
* Detects if a given token is Invalid.
*
* @param Token $token
* @return bool
*/
public function invalidToken(Token $token);
/**
* Is the token Expired?
*
* @param Token $token
* @return bool
*/
public function expired(Token $token);
/**
* Is the token Expired?
*
* @param Token $token
* @return bool
*/
public function canBeRenewed(Token $token);
}
================================================
FILE: src/ServiceProvider.php
================================================
<?php
namespace Codecasts\Auth\JWT;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Routing\Events\RouteMatched;
use Illuminate\Support\Arr;
use Illuminate\Support\ServiceProvider as LaravelServiceProvider;
use Codecasts\Auth\JWT\Auth\Guard;
use Codecasts\Auth\JWT\Console\KeyGenerateCommand;
use Codecasts\Auth\JWT\Contracts;
use Codecasts\Auth\JWT\Token\Manager;
use Codecasts\Auth\JWT\Auth\ServiceProvider as AuthServiceProvider;
/**
* Codecasts JWT Auth for Laravel 5.4
*
* Main Service provider.
*/
class ServiceProvider extends LaravelServiceProvider
{
/**
* Yes, the base class already has $defer as false.
* But in case the Laravel API changes that in the future,
* this attribute makes sure that this provider cannot be deferred.
*
* @var bool
*/
protected $defer = false;
/**
* Boots the Service provider.
*/
public function boot()
{
// declare the configuration files available for publishing.
$this->publishes([
__DIR__.'/../config/jwt.php' => config_path('jwt.php')
]);
// case enabled, setups a guard match by middleware group name.
$this->setupGuardMiddlewareMatch();
}
public function register()
{
// register contract/concrete bindings.
$this->registerBindings();
// register commands.
$this->registerCommands();
// register the "auth" service provider.
// this is needed in order because that service
// provider needs to inherit from the Laravel
// default service provider, which register policies
// and other resources that are not possible (at least harder)
// to do in a common service provider.
$this->app->register(AuthServiceProvider::class);
}
/**
* Binds Contracts (interfaces) and Concretes (implementations) together.
*/
protected function registerBindings()
{
// bind the manager class.
$this->app->bind(Contracts\Token\Manager::class, Manager::class);
// bind the guard class.
$this->app->bind(Contracts\Auth\Guard::class, Guard::class);
}
/**
* Register console commands this package provides.
*/
protected function registerCommands()
{
$this->commands([
// "jwt:generate" command (generates keys).
KeyGenerateCommand::class,
]);
}
/**
* Setup the current guard to be matched by route middleware name.
*/
protected function setupGuardMiddlewareMatch()
{
// should the middleware group match the guard name?
$middlewareMatch = $this->app['config']->get('jwt.middleware_match', true);
if ($middlewareMatch) {
// when the route is actually matched...
$this->app['router']->matched(function (RouteMatched $event) {
// get the route middleware group.
$middlewareGroup = Arr::first((array) $event->route->middleware());
// if there is a group detected and there is a guard that matches the middleware
// group name...
if ($middlewareGroup && !!$this->app['auth']->guard($middlewareGroup)) {
// setup the matching guard as default.
$this->app['auth']->setDefaultDriver($middlewareGroup);
}
});
}
}
}
================================================
FILE: src/Token/Manager.php
================================================
<?php
namespace Codecasts\Auth\JWT\Token;
use Carbon\Carbon;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Config\Repository as Config;
use Illuminate\Cache\Repository as Cache;
use Illuminate\Support\Str;
use Codecasts\Auth\JWT\Contracts\Token\Manager as ManagerContract;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Lcobucci\JWT\Token;
/**
* JWT Token Manager.
*/
class Manager implements ManagerContract
{
/**
* @var \Illuminate\Config\Repository
*/
protected $config;
/**
* @var \Illuminate\Cache\Repository
*/
protected $cache;
/**
* JWT Issuer (API Hostname).
*
* @var String
*/
protected $issuer;
/**
* Secret that will be used to sign tokens.
*
* @var string
*/
protected $secret = null;
/**
* Token time to live (TTL, in minutes).
*
* @var int
*/
protected $ttl = 60;
/**
* Refresh after expired limit (in minutes).
*
* @var int
*/
protected $refreshLimit = 7200;
/**
* JWT Builder.
*
* @var \Lcobucci\JWT\Builder
*/
protected $builderClass = Builder::class;
/**
* JWT Parser Class.
*
* @var \Lcobucci\JWT\Parser
*/
protected $parserClass = Parser::class;
/**
* JWT HMAC-SHA256 Signer.
*
* @var \Lcobucci\JWT\Signer\Hmac\Sha256
*/
protected $signerClass = Sha256::class;
/**
* Token Manager constructor.
*
* @param \Illuminate\Config\Repository $config
* @param \Illuminate\Cache\Repository $cache
*/
public function __construct(Config $config, Cache $cache)
{
// setup repositories.
$this->config = $config; //config repository.
$this->cache = $cache; // cache repository.
// setup the secret that will be used to sign keys.
$this->setupSecret();
// setup other config resources.
$this->setupConfig();
}
/**
* Setup the secret that will be used to sign keys.
*/
public function setupSecret()
{
// gets the key from config.
$secret = $this->config->get('jwt.secret');
// if the secret is in a base64 format, unwrap it's value
if (Str::startsWith($secret, 'base64:')) {
// remove the 'base64:' part and decode the value.
$secret = base64_decode(substr($secret, 7));
}
// set the secret on the local scope.
$this->secret = $secret;
// if the secret is not valid,
// throw an exception to avoid continuing.
if (!$this->validSecret()) {
throw new \Exception('Invalid Secret (not present or too short). Use php artisan jwt:generate to create a valid key.');
}
}
/**
* Determines if the current secret is valid and secure enough.
* Of course it will only check for size since there's no way
* (that I know of) of check if a value is really random.
*
* @return bool
*/
protected function validSecret()
{
// this method is intentionally broken in two pieces
// so the logic will be loud and clear.
// is the secret empty?
if (empty($this->secret)) {
return false;
}
// created a hex representation of the secret.
$hexRepresentation = bin2hex($this->secret);
// check for the secret's hex representation length...
// hex size is deterministic, it's a way of counting bytes from binary
// ( SORT OF)
// in any case, the length will double of the binary random generated secret.
// 16 bytes secret will have a hex of length 32
// 32 bytes secret will have a hex of length 64
// 64 bytes secret will have a hex of length 128
// you get it right?
if ((Str::length($hexRepresentation) / 2) < 16) {
// the minimum secret size should be 16
// so return false in case the secret
// is shorter than that.
return false;
}
// after all this checks, declare the secret valid (finally).
return true;
}
/**
* Setup JWT configuration.
*/
protected function setupConfig()
{
// setup time to live (in minutes), defaults to 60.
$this->ttl = $this->config->get('jwt.ttl', 60);
// setup refresh limit (in minutes), defaults to 7200 (5 days)
$this->refreshLimit = $this->config->get('jwt.refresh_limit', 7200);
// set the token issuer (domain name).
$this->issuer = url('');
}
/**
* Returns a new Signer instance.
*
* @return Sha256
*/
protected function signer()
{
return app()->make($this->signerClass);
}
/**
* Returns a new Builder instance.
*
* @return Builder
*/
protected function builder()
{
return app()->make($this->builderClass);
}
/**
* Returns a new Parser instance.
*
* @return Parser
*/
protected function parser()
{
return app()->make($this->parserClass);
}
/**
* Create a carbon object with current time and date.
* @return Carbon
*/
protected function now()
{
return Carbon::now('UTC');
}
/**
* Generates a random short ID to be used as the token id.
*
* This id is actually used only for blacklisting the tokens, not need for
* additional security.
*
* @return string
*/
protected function generateId()
{
return Str::random(16);
}
/**
* @param Authenticatable $user
* @param array $additionalCustomClaims
*
* @return string
*/
public function issue(Authenticatable $user, array $additionalCustomClaims = [])
{
// gets a new builder instance.
$builder = $this->builder();
// set the issued
$builder->setIssuer($this->issuer);
// set the subject.
$builder->setSubject($user->getAuthIdentifier());
// generate a unique id for the token, and set it to replicate as a header.
$builder->setId($this->generateId(), true);
// detect what time is it.
$now = $this->now();
// set issue date.
$builder->setIssuedAt($now->timestamp);
// set the token cannot be used before now.
$builder->setNotBefore($now->timestamp);
// calculate and set the expiration date for the token.
$expiresAt = (clone $now)->addMinutes($this->ttl);
$builder->setExpiration($expiresAt->timestamp);
// created a custom claim that informs the limit time
// for the token to be renewed.
// the refresh limit is based on ttl + limit (grace period).
$refreshLimit = (clone $now)->addMinutes($this->ttl + $this->refreshLimit);
$builder->set('rli', $refreshLimit->timestamp);
// loop through custom claims.
foreach($additionalCustomClaims as $claim => $value) {
// set custom claim.
$builder->set($claim, $value);
}
// set user object default custom claims.
if (method_exists($user, 'customJWTClaims')) {
// call the methods.
try {
// call the custom claims method.
$customClaims = (array) $user->customJWTClaims();
// if the custom claims method returns a array.
foreach($customClaims as $claim => $value) {
$builder->set($claim, $value);
}
} catch(\Exception $e) {
// just continue since the custom claims should
// not prevent the token of being issued.
}
}
// get the signer.
$signer = $this->signer();
// sign the configure token.
$builder->sign($signer, $this->secret);
// gets the actual signed token as string.
$token = (string) $builder->getToken();
// returns the token.
return $token;
}
/**
* Verify the signature of a given token object.
*
* @param Token $token
* @return bool
*/
protected function verify(Token $token)
{
// the verification is made against the secret key.
// this will not check of expiration, only for signature checking.
return $token->verify($this->signer(), $this->secret);
}
/**
* Method for parsing a token from a string.
*
* @param string $tokenString
*
* @return Token
*/
public function parseToken(string $tokenString)
{
// try to parse a token string.
try {
return $this->parser()->parse($tokenString);
} catch (\Exception $e) {
// if it was not possible to, return null.
return null;
}
}
/**
* Detects if a given token is valid or not.
*
* @param Token $token
*
* @return bool
*/
public function validToken(Token $token)
{
return $this->verify($token);
}
/**
* Detects if a given token is Invalid.
*
* @param Token $token
* @return bool
*/
public function invalidToken(Token $token)
{
return !$this->validToken($token);
}
/**
* Is the token Expired?
*
* @param Token $token
* @return bool
*/
public function expired(Token $token)
{
return $token->isExpired();
}
/**
* Is the token Expired?
*
* @param Token $token
* @return bool
*/
public function canBeRenewed(Token $token)
{
if(!$token->isExpired()) {
return true;
}
// get the renewal limit from token.
$renewalLimitTimestamp = $token->getClaim('rli', null);
// if no renewal limit exists, it means
// that it should not be renewed.
if (!$renewalLimitTimestamp) {
return false;
}
// created a UTC carbon object using the renewal limit.
$limit = Carbon::createFromTimestampUTC($renewalLimitTimestamp);
// get a UTC carbon object that represents now.
$now = $this->now();
// return true if now if before the limit.
return $now->lessThanOrEqualTo($limit);
}
}
================================================
FILE: tests/Auth/GuardTest.php
================================================
<?php
namespace Tests\Auth\Guard;
use Tests\TestCase;
class GuardTest extends TestCase
{
}
================================================
FILE: tests/TestCase.php
================================================
<?php
namespace Tests;
use Codecasts\Auth\JWT\ServiceProvider;
class TestCase extends \Orchestra\Testbench\TestCase
{
public function getPackageProviders()
{
return [ServiceProvider::class, AuthService::class];
}
}
gitextract_u6zs6ejr/
├── .github/
│ └── workflows/
│ └── build.yml
├── .gitignore
├── .travis.yml
├── CONTRIBUTING.md
├── LICENSE.txt
├── composer.json
├── config/
│ └── jwt.php
├── phpunit.xml
├── readme.md
├── sonar-project.properties
├── src/
│ ├── Auth/
│ │ ├── Guard.php
│ │ └── ServiceProvider.php
│ ├── Console/
│ │ └── KeyGenerateCommand.php
│ ├── Contracts/
│ │ ├── Auth/
│ │ │ └── Guard.php
│ │ └── Token/
│ │ └── Manager.php
│ ├── ServiceProvider.php
│ └── Token/
│ └── Manager.php
└── tests/
├── Auth/
│ └── GuardTest.php
└── TestCase.php
SYMBOL INDEX (83 symbols across 9 files)
FILE: src/Auth/Guard.php
class Guard (line 23) | class Guard implements GuardContract
method __construct (line 109) | public function __construct($app, $name, $provider, $manager)
method fireAttemptEvent (line 124) | protected function fireAttemptEvent(array $credentials)
method fireFailedEvent (line 140) | protected function fireFailedEvent($user, array $credentials)
method fireLoginEvent (line 154) | protected function fireLoginEvent($user)
method validate (line 167) | public function validate(array $credentials = [])
method attempt (line 180) | public function attempt(array $credentials = [])
method hasValidCredentials (line 210) | protected function hasValidCredentials($user, $credentials)
method login (line 221) | public function login(Authenticatable $user)
method getTokenFromHeader (line 236) | protected function getTokenFromHeader()
method getTokenFromParameter (line 256) | protected function getTokenFromParameter()
method detectedToken (line 270) | protected function detectedToken()
method findUserByToken (line 290) | protected function findUserByToken(Token $token)
method user (line 305) | public function user()
method logout (line 355) | public function logout()
method manager (line 369) | public function manager()
method issue (line 380) | public function issue(array $customClaims = [])
method refresh (line 403) | public function refresh(string $token = null, array $customClaims = [])
method getDispatcher (line 443) | public function getDispatcher()
method setDispatcher (line 454) | public function setDispatcher(Dispatcher $events)
method getRequest (line 464) | public function getRequest()
method setRequest (line 475) | public function setRequest(Request $request)
method getToken (line 487) | public function getToken()
FILE: src/Auth/ServiceProvider.php
class ServiceProvider (line 14) | class ServiceProvider extends AuthServiceProvider
method register (line 26) | public function register()
method getUserProvider (line 59) | protected function getUserProvider($alias)
method getTokenManager (line 69) | protected function getTokenManager()
FILE: src/Console/KeyGenerateCommand.php
class KeyGenerateCommand (line 14) | class KeyGenerateCommand extends Command
method fire (line 30) | public function fire()
method handle (line 38) | public function handle()
method setKeyInEnvironmentFile (line 78) | protected function setKeyInEnvironmentFile($key)
method writeNewEnvironmentFileWith (line 96) | protected function writeNewEnvironmentFileWith($key)
method generateRandomKey (line 110) | protected function generateRandomKey()
method printBlock (line 122) | protected function printBlock(array $lines, $style, $firstBlock = false)
method keyReplacementPattern (line 150) | protected function keyReplacementPattern()
FILE: src/Contracts/Auth/Guard.php
type Guard (line 11) | interface Guard extends LaravelGuard
method __construct (line 21) | public function __construct($app, $name, $provider, $manager);
method validate (line 27) | public function validate(array $credentials = []);
method attempt (line 35) | public function attempt(array $credentials = []);
method login (line 43) | public function login(Authenticatable $user);
method logout (line 50) | public function logout();
method manager (line 57) | public function manager();
method refresh (line 66) | public function refresh(string $token = null, array $customClaims = []);
method issue (line 74) | public function issue(array $customClaims = []);
method getDispatcher (line 81) | public function getDispatcher();
method setDispatcher (line 89) | public function setDispatcher(Dispatcher $events);
method getRequest (line 96) | public function getRequest();
method setRequest (line 104) | public function setRequest(Request $request);
FILE: src/Contracts/Token/Manager.php
type Manager (line 10) | interface Manager
method __construct (line 18) | public function __construct(Config $config, Cache $cache);
method setupSecret (line 23) | public function setupSecret();
method issue (line 31) | public function issue(Authenticatable $user, array $customClaims = []);
method parseToken (line 40) | public function parseToken(string $tokenString);
method validToken (line 49) | public function validToken(Token $token);
method invalidToken (line 57) | public function invalidToken(Token $token);
method expired (line 65) | public function expired(Token $token);
method canBeRenewed (line 73) | public function canBeRenewed(Token $token);
FILE: src/ServiceProvider.php
class ServiceProvider (line 20) | class ServiceProvider extends LaravelServiceProvider
method boot (line 34) | public function boot()
method register (line 46) | public function register()
method registerBindings (line 66) | protected function registerBindings()
method registerCommands (line 78) | protected function registerCommands()
method setupGuardMiddlewareMatch (line 89) | protected function setupGuardMiddlewareMatch()
FILE: src/Token/Manager.php
class Manager (line 19) | class Manager implements ManagerContract
method __construct (line 86) | public function __construct(Config $config, Cache $cache)
method setupSecret (line 102) | public function setupSecret()
method validSecret (line 130) | protected function validSecret()
method setupConfig (line 165) | protected function setupConfig()
method signer (line 182) | protected function signer()
method builder (line 192) | protected function builder()
method parser (line 202) | protected function parser()
method now (line 211) | protected function now()
method generateId (line 224) | protected function generateId()
method issue (line 235) | public function issue(Authenticatable $user, array $additionalCustomCl...
method verify (line 310) | protected function verify(Token $token)
method parseToken (line 324) | public function parseToken(string $tokenString)
method validToken (line 342) | public function validToken(Token $token)
method invalidToken (line 353) | public function invalidToken(Token $token)
method expired (line 364) | public function expired(Token $token)
method canBeRenewed (line 375) | public function canBeRenewed(Token $token)
FILE: tests/Auth/GuardTest.php
class GuardTest (line 7) | class GuardTest extends TestCase
FILE: tests/TestCase.php
class TestCase (line 7) | class TestCase extends \Orchestra\Testbench\TestCase
method getPackageProviders (line 9) | public function getPackageProviders()
Condensed preview — 19 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (56K chars).
[
{
"path": ".github/workflows/build.yml",
"chars": 579,
"preview": "name: Build\non:\n push:\n branches:\n - master\n pull_request:\n types: [opened, synchronize, reopened]\njobs:\n "
},
{
"path": ".gitignore",
"chars": 22,
"preview": "composer.lock\n/vendor\n"
},
{
"path": ".travis.yml",
"chars": 371,
"preview": "language: php\n\nsudo: false\n\ngit:\n depth: 2\n\nmatrix:\n include:\n - php: 7.0\n - php: 7.1\n - php: 7.2\n - php: "
},
{
"path": "CONTRIBUTING.md",
"chars": 1342,
"preview": "# Contributing\n\nContributions are **welcome** and will be fully **credited**.\n\nWe accept contributions via Pull Requests"
},
{
"path": "LICENSE.txt",
"chars": 1094,
"preview": "MIT License\n\nCopyright (c) 2017 Diego Hernandes <diego@hernandev.com>\n\nPermission is hereby granted, free of charge, to "
},
{
"path": "composer.json",
"chars": 942,
"preview": "{\n \"name\": \"codecasts/laravel-jwt\",\n \"description\": \"Dead simple JWT Auth Provider for Laravel 5.4+\",\n \"type\": "
},
{
"path": "config/jwt.php",
"chars": 3772,
"preview": "<?php\n\n /*\n |--------------------------------------------------------------------------\n | GENERAL WARNING. DO "
},
{
"path": "phpunit.xml",
"chars": 677,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phpunit backupGlobals=\"false\"\n backupStaticAttributes=\"false\"\n b"
},
{
"path": "readme.md",
"chars": 6322,
"preview": "\n\n\n# Laravel JWT\n\n[. The extraction includes 19 files (51.4 KB), approximately 12.5k tokens, and a symbol index with 83 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.