Quick start for Laravel 5.7 + Angular 7.0 projects with passport auth.
- Angular CLI boilerplate files
- JWT authentication service
- Login/Register components (Angular Material)
- Password reset components
- Composer build file
- Boilerplate files
- JWT authentication
- Password reset functionality
- Install PHP and one of the following Databases: MySQL, PostgreSQL, MS SQL Server or SQL Lite.
- Install Composer and nodeJS.
- Go to
Server
folder and runcomposer install
to install dependencies. - Set your DB connections in
.env
: DB_CONNECTION (mysql, pgsql, sqlsrv, sqlite), DB_DATABASE, DB_PORT, DB_USERNAME, DB_PASSWORD. For email sending make sure that you have in your .env file next keys set:MAIL_DRIVER
,MAIL_HOST
,MAIL_PORT
,MAIL_USERNAME
,MAIL_PASSWORD
,MAIL_ENCRYPTION
. Fou production build change environment to production:APP_ENV=production
. - To update your DB to current version go to
Server
folder and runphp artisan migrate
. If you want to rollback old migration usephp artisan migrate:rollback
. - (optional) If you want to change
APP_KEY
runphp artisan key:generate
to generate app key. If you get any error on key generation, check if lineAPP_KEY=
exists in.env
, then rerun command. Make sure that apache has access to write intoServer/bootstrap/cache
andServer/storage
folders. - (optional) If you want to change JWT secret run
php artisan jwt:generate
to generate secret for API.
- Install nodeJS
- Globally install Angular CLI using command
npm install -g @angular/cli@latest
- Open Client folder in terminal/console and run
npm i
to install all dependencies - Add URL to your local server to
/Client/src/environments/environment.ts
- Run
ng serve
for a dev server. Navigate tohttp://localhost:4200/
. The app will automatically reload if you change any of the source files. - If you want to generate a new component run
ng generate component component-name
. You can also useng generate directive|pipe|service|class|guard|interface|enum|module
. - Run
ng build -prod
inClient
directory to build angular client. The build artifacts will be stored in thedist/
directory.
License: MIT# flavour_vote
Laravel Passport is definitely the best option for api token authentication in Laravel based apps. It automatically generates api token in Laravel apps. This make it easy to configure and efficient to use in your apps.
Open your terminal and type the command below to install a new Laravel on your system
laravel new myApp
Laravel Passport provides full 0Auth2 server authentication which makes it a great deal
composer require laravel/passport
Run Migration to generate the tables to store client and access token
However, there are two important keys needed by the application to generate secure access token; "Personal Access" and "Password Grant"
php artisan passport:install
Or
php artisan passport:client --personal
This creates client ID and Client secret.
NOTE: add the Laravel\Passport\HasApiTokens trait to your App\Usermodel. This trait will provide a few helper methods to your model which allows you to inspect the authenticated user's token and scopes
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use Notifiable, HasApiTokens;
}
Next, you should call the Passport::routes() method within the boot method of your AuthServiceProvider. This method will register the routes necessary to issue access tokens and revoke access tokens, clients, and personal access tokens:
<?php
namespace App\Providers;
use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Passport::routes();
}
}
Open config/auth.php configuration file, you should set the driver option of the api authentication guard to passport. This will tell your application to use Passport's TokenGuard when authenticating incoming API requests:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
Open routes/api.php file to write web services route.
use Illuminate\Http\Request;
Route::group([
'prefix' => 'auth'
], function () {
Route::post('login', 'AuthController@login');
Route::post('signup', 'AuthController@signup');
Route::group([
'middleware' => 'auth:api'
], function() {
Route::get('logout', 'AuthController@logout');
Route::get('user', 'AuthController@user');
});
});
php artisan make:controller AuthController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Carbon\Carbon;
use App\User;
class AuthController extends Controller
{
/**
* Create user
*
* @param [string] name
* @param [string] email
* @param [string] password
* @param [string] password_confirmation
* @return [string] message
*/
public function signup(Request $request)
{
$request->validate([
'name' => 'required|string',
'email' => 'required|string|email|unique:users',
'password' => 'required|string|confirmed'
]);
$user = new User([
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password)
]);
$user->save();
return response()->json([
'message' => 'Successfully created user!'
], 201);
}
/**
* Login user and create token
*
* @param [string] email
* @param [string] password
* @param [boolean] remember_me
* @return [string] access_token
* @return [string] token_type
* @return [string] expires_at
*/
public function login(Request $request)
{
$request->validate([
'email' => 'required|string|email',
'password' => 'required|string',
'remember_me' => 'boolean'
]);
$credentials = request(['email', 'password']);
if(!Auth::attempt($credentials))
return response()->json([
'message' => 'Unauthorized'
], 401);
$user = $request->user();
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;
if ($request->remember_me)
$token->expires_at = Carbon::now()->addWeeks(1);
$token->save();
return response()->json([
'access_token' => $tokenResult->accessToken,
'token_type' => 'Bearer',
'expires_at' => Carbon::parse(
$tokenResult->token->expires_at
)->toDateTimeString()
]);
}
/**
* Logout user (Revoke the token)
*
* @return [string] message
*/
public function logout(Request $request)
{
$request->user()->token()->revoke();
return response()->json([
'message' => 'Successfully logged out'
]);
}
/**
* Get the authenticated User
*
* @return [json] user object
*/
public function user(Request $request)
{
return response()->json($request->user());
}
}
Let's start by adding some columns in users table as follows;
we add two columns active and activation_token also we add the *softDeletes trait in database/migrations/xxxx_create_users_table.php migration file.
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->boolean('active')->default(false);
$table->string('activation_token');
$table->rememberToken();
$table->timestamps();
$table->softDeletes();
});
}
...
we add SoftDeletes trait, fillable and hidden attributes in your App\User model.
<?php
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Passport\HasApiTokens;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Authenticatable
{
use Notifiable, HasApiTokens, SoftDeletes;
protected $dates = ['deleted_at'];
protected $fillable = [
'name', 'email', 'password', 'active', 'activation_token'
];
protected $hidden = [
'password', 'remember_token', 'activation_token'
];
}
Run php artisan migrate:refresh to migrate
Run php artisan make:notification SignupActivate to create a signup notification and confirmation -> app/Notifications/SignupActivate.php will be created, then open it and replace toMail function with this
public function toMail($notifiable)
{
$url = url('/api/auth/signup/activate/'.$notifiable->activation_token);
return (new MailMessage)
->subject('Confirm your account')
->line('Thanks for signup! Please before you begin, you must confirm your account.')
->action('Confirm Account', url($url))
->line('Thank you for using our application!');
}
In your app/Http/Controllers/AuthController.php controller, let’s update AuthController and put the code below
<?php
...
use App\Notifications\SignupActivate;
class AuthController extends Controller
{
...
public function signup(Request $request)
{
$request->validate([
'name' => 'required|string',
'email' => 'required|string|email|unique:users',
'password' => 'required|string|confirmed'
]);
$user = new User([
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password),
'activation_token' => str_random(60)
]);
$user->save();
$user->notify(new SignupActivate($user));
return response()->json([
'message' => 'Successfully created user!'
], 201);
}
}
Add this to the routes; Route::get('signup/activate/{token}', 'AuthController@signupActivate');
Add this function to your AuthController
public function signupActivate($token)
{
$user = User::where('activation_token', $token)->first();
if (!$user) {
return response()->json([
'message' => 'This activation token is invalid.'
], 404);
}
$user->active = true;
$user->activation_token = '';
$user->save();
return $user;
}
To validate that account is active and has not been deleted we update login method of app/Http/Controllers/AuthController.php controller.
public function login(Request $request)
{
$request->validate([
'email' => 'required|string|email',
'password' => 'required|string',
'remember_me' => 'boolean'
]);
$credentials = request(['email', 'password']);
$credentials['active'] = 1; //added to validate
$credentials['deleted_at'] = null; //added to validate
if(!Auth::attempt($credentials))
return response()->json([
'message' => 'Unauthorized'
], 401);
$user = $request->user();
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;
if ($request->remember_me)
$token->expires_at = Carbon::now()->addWeeks(1);
$token->save();
return response()->json([
'access_token' => $tokenResult->accessToken,
'token_type' => 'Bearer',
'expires_at' => Carbon::parse($tokenResult->token->expires_at)->toDateTimeString()
]);
}
You will need to do some settings on your account, especially if you want to use SMTP and besides gmail account. Go to your gmail account to enable 2-verification and generate app password. Then go to .env
MAIL_DRIVER=smtp MAIL_HOST=smtp.gmail.com MAIL_PORT=587 MAIL_USERNAME=[email protected] MAIL_PASSWORD= MAIL_ENCRYPTION=tls
config/mail.php
return [
'driver' => env('MAIL_DRIVER', 'smtp'),
'host' => env('MAIL_HOST', 'smtp.gmail.com'),
'port' => env('MAIL_PORT', 587),
'from' => [
'address' => env('MAIL_FROM_ADDRESS', '[email protected]'),
'name' => env('MAIL_FROM_NAME', 'Payne Curtis'),
],
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
'sendmail' => '/usr/sbin/sendmail -bs',
'markdown' => [
'theme' => 'default',
'paths' => [
resource_path('views/vendor/mail'),
],
],
'log_channel' => env('MAIL_LOG_CHANNEL'),
];