Laravel: Set custom Authentication user as the logged in user - php

I have created a custom authentication class which get's called from middleware, this will forward the user to AWS Cognito Hosted UI, the user will login then get returned to the application with a authorization code. This code is then exchanged for the access_token, id_token and refresh_token.
Once the access_token and id_token has been validated using the jwks keys I can extract the users email address and then return this within the User model which extends Authenticatable. Then i'd like to use $user within my Twig templates the same way i can with the default login system for Laravel.
Below is my code:
// config/auth.php
'guards' => [
'web' => [
'driver' => 'cognito',
'provider' => 'users',
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User\User::class,
],
// app/Providers/AuthServiceProvider.php
public function boot()
{
$this->registerPolicies();
Auth::extend('cognito', static function ($app, $name, array $config) {
return new CognitoUserProvider(new User());
});
}
// app/Auth/CognitoUserProvider.php
<?php
namespace App\Auth;
use App\Models\User;
use Firebase\JWT\JWT;
use GuzzleHttp\Client;
use CoderCat\JWKToPEM\JWKConverter;
class CognitoUserProvider
{
private $user;
private $clientId;
private $clientSecret;
private $poolId;
private $region;
private $domain;
private $guzzle;
public function __construct(User $user)
{
$this->clientSecret = config('app.aws_cognito_client_secret');
$this->poolId = config('app.aws_cognito_pool_id');
$this->clientId = config('app.aws_cognito_client_id');
$this->region = config('app.aws_region');
$this->domain = implode('.', [
config('app.aws_cognito_domain'),
'auth',
config('app.aws_region'),
'amazoncognito.com'
]);
$this->guzzle = new Client();
$this->user = $user;
}
/**
* #return User|bool|void
*/
public function authenticate()
{
if (request()->input('code')) {
$tokens = $this->exchangeTokens();
$accessToken = $this->validateToken($tokens['access_token']);
$userToken = $this->validateToken($tokens['id_token']);
if (!$accessToken || !$userToken) {
dd('JsonException Exception Occurred.');
}
request()->session()->put('access_token', $accessToken);
request()->session()->put('id_token', $userToken);
request()->session()->put('refresh_token', $tokens['refresh_token']);
$this->user->setAttribute('email', $userToken->email);
$this->user->setAttribute('first_name', 'Martyn');
$this->user->setAttribute('last_name', 'Ball');
$this->user->setAttribute('id', 5);
return $this->user;
}
if (request()->session()->has('refresh_token')) {
return $this->refreshToken();
}
$this->sendToLoginPage();
}
/**
* #param $token
*
* #return false|object
*/
private function validateToken($token)
{
$domain = implode('.', [ 'cognito-idp', $this->region, 'amazonaws.com' ]);
$jwks = file_get_contents("https://$domain/{$this->poolId}/.well-known/jwks.json");
try {
$jwks = collect(json_decode($jwks, true, 512, JSON_THROW_ON_ERROR)['keys']);
$jwks = $jwks->keyBy('kid')->map(static function ($current) {
return (new JWKConverter())->toPEM($current);
})->toArray();
$jwt = new JWT();
$jwt::$leeway = config('app.jwt_leeway');
return $jwt::decode($token, $jwks, ['RS256']);
} catch (\JsonException $e) {
return false;
}
}
/**
* #return false|mixed
*/
private function exchangeTokens()
{
$params = [
'grant_type' => 'authorization_code',
'client_id' => $this->clientId,
'code' => request()->input('code'),
'redirect_uri' => 'https://localhost/',
];
$result = $this->guzzle->post("https://{$this->domain}/oauth2/token?".http_build_query($params), [
'headers' => [
'Content-Type' => 'application/x-www-form-urlencoded',
'Authorization' => 'Basic '.base64_encode("{$this->clientId}:{$this->clientSecret}")
]
]);
if ($result->getStatusCode() === 200) {
try {
return json_decode($result->getBody()->getContents(), true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
return false;
}
}
return false;
}
/**
* #return void
*/
private function sendToLoginPage(): void
{
$query = http_build_query([
'client_id' => $this->clientId,
'response_type' => 'code',
'redirect_uri' => 'https://localhost/'
]);
header("Location: https://{$this->domain}/login?$query&scope=email+openid");
exit;
}
/**
* #return void
*/
public function logout(): void
{
dd(debug_backtrace());
}
}

Related

RestFul API For Delete And Update Get 403 Forbidden Codeigniter 4

Remember this is codeigniter 4.
I need help in here. I am learning to implement about the RestFul API in codeigniter 4.
Below is my detail code.
Routes :
$routes->resource('ApiManageMaintenance', ['controller' =>'App\Controllers\ApiData\ApiManageMaintenance']); // get, put, create, delete
ApiManageMaintenance.php :
<?php
namespace App\Controllers\ApiData;
use App\Controllers\BaseController;
use CodeIgniter\RESTful\ResourceController;
class ApiManageMaintenance extends ResourceController
{
function __construct()
{
$model = new Dennis_setting_model();
}
// equal to get
public function index()
{
$Medoo = new \App\Models\Dennis_medoo_model();
$result = $Medoo->SelectAllMaintenance();
$response = [
'status' => 200,
'error' => null,
'messages' => 'Pull Data Successfull',
'data' => $result
];
return json_encode($response);
}
// equal to post
public function create() {
$version = $this->request->getVar('version');
$reason = $this->request->getVar('reason');
if ($version == "" || $reason == "") {
$response = [
'status' => 102,
'error' => 'Data Error',
'messages' => 'Data Not Valid',
'data' => null
];
return json_encode($response);
}
$array = array ('version' => $version,
'reason' => $reason
);
$Medoo = new \App\Models\Dennis_medoo_model();
$Medoo->InsertNewMaintenance($array);
$response = [
'status' => 200,
'error' => null,
'messages' => 'Create New Maintenance Successfull',
'data' => null
];
return json_encode($response);
}
// equal to get
public function show($id = null) {
$Medoo = new \App\Models\Dennis_medoo_model();
$result = $Medoo->SelectAllMaintenance();
$response = [
'status' => 200,
'error' => null,
'messages' => 'Pull Data Successfull',
'data' => $result
];
return json_encode($response);
}
// equal to put
public function update($id = null) {
$data = $this->request->getRawInput();
$data['id'] = $id;
$response = [
'status' => 200,
'error' => null,
'messages' => 'Update Data Successfull',
'data' => null
];
return json_encode($response);
}
// equal to delete
public function delete($id = null) {
$Medoo = new \App\Models\Dennis_medoo_model();
$Medoo->DeleteMaintenance($id);
$response = [
'status' => 200,
'error' => null,
'messages' => 'Delete Data Successfull',
'data' => null
];
return json_encode($response);
}
}
Config Filter.php
<?php namespace Config;
use CodeIgniter\Config\BaseConfig;
class Filters extends BaseConfig
{
// Makes reading things below nicer,
// and simpler to change out script that's used.
public $aliases = [
'csrf' => \CodeIgniter\Filters\CSRF::class,
'toolbar' => \CodeIgniter\Filters\DebugToolbar::class,
'honeypot' => \CodeIgniter\Filters\Honeypot::class,
'auth' => \App\Filters\Auth::class,
'authaccess' => \App\Filters\AuthAccess::class
];
// Always applied before every request
public $globals = [
'before' => [
//'honeypot'
'csrf' => ['except' => [
'api/ApiManageMaintenance/delete'
]
]
],
'after' => [
'toolbar',
//'honeypot'
],
];
// Works on all of a particular HTTP method
// (GET, POST, etc) as BEFORE filters only
// like: 'post' => ['CSRF', 'throttle'],
public $methods = [
];
// List filter aliases and any before/after uri patterns
// that they should run on, like:
// 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']],
public $filters = [];
}
Note : I am using thirdparty database library => Medoo, So just ignore it. I am not using the build in framework database query in codeigniter for some reason because Medoo is looking light and simple for me.
Then For Is Working :
Restful API : create => Working => Test With Postman Method : POST
Restful API : show / index => Working => Test With Postman Method : GET
https://somedomain.id/index.php/ApiManageMaintenance
Then For Not Working :
Restful API : update => Not Working => Test With Postman Method : PUT
Restful API : delete => Not Working => Test With Postman Method : DELETE
https://somedomain.id/index.php/ApiManageMaintenance/7
Restful API delete and update both give me an error when try in postman :
403 - Forbidden: Access is denied. You do not have permission to view
this directory or page using the credentials that you supplied.
I also add execption in config => filter.php
public $globals = [
'before' => [
//'honeypot'
'csrf' => ['except' => [
'api/ApiManageMaintenance/delete'
]
]
],
];
I dont really understand the config filter.php but it seem this line of code will make the api delete working.
'csrf' => ['except' => [
'api/ApiManageMaintenance/delete'
]
]
Now my question are :
Is there any specific setup or configuration I miss or I need to do
for Restfu API to make API Restfull working ?
Any help from this community is very appreciate.
The Answer :
Create File Filter in Folder Filters in Codeigniter 4
Put this code :
<?php
namespace App\Filters;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Filters\FilterInterface;
use Codeigniter\API\ResponseTrait;
use Config\Services;
use Exception;
class FilterBasicAuth implements FilterInterface
{
use ResponseTrait;
public function before(RequestInterface $request, $arguments = null)
{
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method, Authorization");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
$method = $_SERVER['REQUEST_METHOD'];
if ($method == "OPTIONS") {
die();
}
}
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
// Do something here
}
}
The main code is :
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method, Authorization");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
$method = $_SERVER['REQUEST_METHOD'];
if ($method == "OPTIONS") {
die();
}
Then in config Filters.php
put and add aliases this code :
public $aliases = [
'cors' => \App\Filters\FilterBasicAuth::class,
];
Note :
I use filter name FilterBasicAuth. You can change to yours and
make sure in the aliases change the name too.
Thats All.
okay the best way implelemnet restfull apici4
api ctl
<?php
namespace Modules\Shared\Controllers;
/**
* Class BaseController
*
* BaseController provides a convenient place for loading components
* and performing functions that are needed by all your controllers.
* Extend this class in any new controllers:
* class Home extends BaseController
*
* For security be sure to declare any new methods as protected or private.
*
* #package CodeIgniter
*/
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\RESTful\ResourceController;
use Modules\Auth\Config\Services;
use Myth\Auth\AuthTrait;
use Psr\Log\LoggerInterface;
use Modules\Shared\Interfaces\UrlAggregationInterface;
use Modules\Shared\Libraries\UrlAggregation;
class ApiController extends ResourceController
{
use AuthTrait;
protected $format = "";
public object $userObject;
public UrlAggregationInterface $urlAggregation;
/**
* An array of helpers to be loaded automatically upon
* class instantiation. These helpers will be available
* to all other controllers that extend BaseController.
*
* #var array
*/
protected $helpers = [
'cookie',
'url',
'from',
'filesystem',
'text',
'shared'
];
/**
* Constructor.
*
* #param RequestInterface $request
* #param ResponseInterface $response
* #param LoggerInterface $logger
*/
/**
* #var string
* Holds the session instance
*/
protected $session;
public function __construct()
{
$this->userObject = (object)[];
}
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
// Do Not Edit This Line
parent::initController($request, $response, $logger);
$this->urlAggregation = new UrlAggregation($request);
$requestWithUser = Services::requestWithUser();
$this->userObject = $requestWithUser->getUser();
}
}
group ctl
<?php namespace Modules\Auth\Controllers;
use Modules\Auth\Config\Services;
use Modules\Auth\Entities\GroupEntity;
use CodeIgniter\HTTP\ResponseInterface;
use Modules\Shared\Controllers\ApiController;
class Group extends ApiController
{
/**
* index function
* #method : GET
*/
public function index()
{
$groupEntity = new GroupEntity();
$this->urlAggregation->dataMap($groupEntity->getDataMap());
$groupService = Services::groupService();
$findAllData = $groupService->index($this->urlAggregation);
return $this->respond([
'data' => $findAllData['data'],
'pager' => $findAllData['pager']
], ResponseInterface::HTTP_OK, lang('Shared.api.receive'));
}
/**
* show function
* #method : GET with params ID
*/
public function show($id = null)
{
$groupService = Services::groupService();
$findOneData = $groupService->show($id);
return $this->respond([
'data' => $findOneData['data'],
'pager' => $findOneData['pager']
], ResponseInterface::HTTP_OK, lang('Shared.api.receive'));
}
public function create()
{
$rules = [
'name' => 'required|min_length[3]|max_length[255]|is_unique[auth_groups.name]',
'description' => 'required|min_length[3]|max_length[255]',
];
if (!$this->validate($rules)) {
return $this->respond([
'error' => $this->validator->getErrors(),
], ResponseInterface::HTTP_NOT_ACCEPTABLE, lang('Shared.api.validation'));
}
$groupEntity = new GroupEntity((array)$this->request->getVar());
$groupService = Services::groupService();
$groupService->create($groupEntity);
return $this->respond([
'data' => ''
], ResponseInterface::HTTP_CREATED, lang('Shared.api.save'));
}
/**
* update function
* #method : PUT or PATCH
*/
public function update($id = null)
{
//get request from Vue Js
//get request from Vue Js
$json = $this->request->getJSON();
if (!isset($id)) {
$id = $json->id;
}
$rules = [
'name' => 'if_exist|required|min_length[3]|max_length[255]',
'description' => 'required|min_length[3]|max_length[255]',
];
if (!$this->validate($rules)) {
return $this->respond([
'error' => $this->validator->getErrors(),
], ResponseInterface::HTTP_NOT_ACCEPTABLE, lang('Shared.api.validation'));
}
$groupEntity = new GroupEntity((array)$this->request->getVar());
$groupService = Services::groupService();
$groupService->update($id, $groupEntity);
return $this->respond([
], ResponseInterface::HTTP_OK, lang('Shared.api.update'));
}
/**
* edit function
* #method : DELETE with params ID
*/
public function delete($id = null)
{
$groupService = Services::groupService();
$groupService->delete($id);
return $this->respond([
], ResponseInterface::HTTP_OK, lang('Shared.api.remove'));
}
}
entitiy
<?php namespace Modules\Auth\Entities;
use \CodeIgniter\Entity;
use CodeIgniter\I18n\Time;
class GroupEntity extends Entity
{
protected $id;
protected $name;
protected $description;
//check type of data
// protected $casts = ['
// is_flag' => 'boolean'];
protected $attributes = [
'id' => null,
'name' => null,
'description' => null,
];
protected $datamap = [
];
protected $dates = [];
protected $casts = [];
protected $permissions = [];
protected $roles = [];
}
service leayer
<?php
namespace Modules\Auth\Services;
use Modules\Auth\Entities\GroupEntity;
use CodeIgniter\HTTP\ResponseInterface;
use Modules\Shared\Interfaces\UrlAggregationInterface;
use Modules\Shared\Libraries\MainService;
use Myth\Auth\Authorization\GroupModel;
class GroupService extends MainService
{
private GroupModel $model;
public function __construct()
{
$this->model = new GroupModel();
}
/**
* index function
* #method : GET
* #param UrlAggregationInterface $urlAggregation
* #return array
*/
public function index(UrlAggregationInterface $urlAggregation)
{
$pipeLine = $urlAggregation->decodeQueryParam()->getPipeLine();
return $this->model->aggregatePagination($pipeLine);
}
/**
* show function
* #method : GET with params ID
* #param $id
* #return array
*/
public function show($id)
{
if (is_null($id)) $this->httpException(lang('Shared.api.validation'), ResponseInterface::HTTP_NOT_FOUND);
$result = $this->model->where('id', $id)->paginate(1, 'default');
if (is_null($result)) $this->httpException(lang('Shared.api.exist'), ResponseInterface::HTTP_NOT_FOUND);
$data = [
'data' => $result,
'pager' => $this->model->pager->getDetails()
];
return $data;
}
/**
* create function
* #method : POST
* #param GroupEntity $entity
* #throws \ReflectionException
*/
public function create(GroupEntity $entity)
{
if (is_null($entity)) $this->httpException(lang('Shared.api.validation'), ResponseInterface::HTTP_NOT_FOUND);
if (!$this->model->save($entity)) {
helper('shared');
$this->httpException(lang('Shared.api.reject'), ResponseInterface::HTTP_BAD_REQUEST,serializeMessages($this->model->errors()));
}
}
/**
* update function
* #method : PUT or PATCH
* #param $id
* #param GroupEntity $entity
* #throws \ReflectionException
*/
public function update($id , GroupEntity $entity)
{
if (is_null($entity)) $this->httpException(lang('Shared.api.validation'), ResponseInterface::HTTP_NOT_FOUND);
if (!$this->model->update($id, $entity)) {
helper('shared');
$this->httpException(lang('Shared.api.reject'), ResponseInterface::HTTP_BAD_REQUEST,serializeMessages($this->model->errors()));
}
}
/**
* edit function
* #method : DELETE with params ID
* #param $id
*/
public function delete($id )
{
$deleteById = $this->model->find($id);
if (is_null($deleteById)) $this->httpException(lang('Shared.api.exist'), ResponseInterface::HTTP_NOT_FOUND);
$this->model->delete($id);
}
public function getInsertId()
{
return $this->model->getInsertID();
}
}
this is part 2
<?php namespace Modules\Auth\Config;
use CodeIgniter\HTTP\UserAgent;
use Config\App;
use Config\Services as AppServices;
use Config\Services as BaseService;
use Modules\Auth\Libraries\RequestWithUser;
use Modules\Auth\Services\AuthService;
use Modules\Auth\Services\GroupsPermissionService;
use Modules\Auth\Services\PermissionService;
use Modules\Auth\Services\RoleRouteService;
use Modules\Auth\Services\GroupService;
use Modules\Auth\Services\UsersPermissionService;
class Services extends BaseService
{
//--------------------------------------------------------------------
/**
* The Request class models an HTTP request.
*
* #param App|null $config
* #param boolean $getShared
*
* #return RequestWithUser
*/
public static function requestWithUser(App $config = null, bool $getShared = true)
{
if ($getShared) {
return static::getSharedInstance('requestWithUser', $config);
}
$config = $config ?? config('App');;
return new RequestWithUser(
$config,
AppServices::uri(),
'php://input',
new UserAgent()
);
}
//--------------------------------------------------------------------
public static function roleRoute($getShared = true)
{
if ($getShared) {
return static::getSharedInstance('roleRoute');
}
return new RoleRouteService();
}
//--------------------------------------------------------------------
public static function authService($getShared = false)
{
if (!$getShared) {
return new AuthService();
}
return static::getSharedInstance('authService');
}
//--------------------------------------------------------------------
public static function groupService($getShared = false)
{
if (!$getShared) {
return new GroupService();
}
return static::getSharedInstance('groupService');
}
//--------------------------------------------------------------------
public static function permissionService($getShared = false)
{
if (!$getShared) {
return new PermissionService();
}
return static::getSharedInstance('permissionService');
}
//--------------------------------------------------------------------
public static function groupsPermissionService($getShared = false)
{
if (!$getShared) {
return new GroupsPermissionService();
}
return static::getSharedInstance('groupsPermissionService');
}
//--------------------------------------------------------------------
public static function userPermissionService($getShared = false)
{
if (!$getShared) {
return new UsersPermissionService();
}
return static::getSharedInstance('usersPermissionService');
}
//--------------------------------------------------------------------
}
model
<?php namespace Myth\Auth\Authorization;
use CodeIgniter\Model;
use Modules\Auth\Entities\GroupEntity;
use Modules\Shared\Models\Aggregation;
class GroupModel extends Aggregation
{
protected $table = 'auth_groups';
protected $primaryKey = 'id';
protected $returnType = GroupEntity::class;
protected $allowedFields = [
'name', 'description'
];
protected $useTimestamps = false;
protected $validationRules = [
'name' => 'required|max_length[255]|is_unique[auth_groups.name,name,{name}]',
'description' => 'max_length[255]',
];
protected $validationMessages = [];
protected $skipValidation = false;
//--------------------------------------------------------------------
// Users
//--------------------------------------------------------------------
/**
* Adds a single user to a single group.
*
* #param int $userId
* #param int $groupId
*
* #return bool
*/
public function addUserToGroup(int $userId, int $groupId)
{
cache()->delete("{$groupId}_users");
cache()->delete("{$userId}_groups");
cache()->delete("{$userId}_permissions");
$data = [
'user_id' => (int) $userId,
'group_id' => (int) $groupId
];
return (bool) $this->db->table('auth_groups_users')->insert($data);
}
/**
* Removes a single user from a single group.
*
* #param int $userId
* #param int|string $groupId
*
* #return bool
*/
public function removeUserFromGroup(int $userId, $groupId)
{
cache()->delete("{$groupId}_users");
cache()->delete("{$userId}_groups");
cache()->delete("{$userId}_permissions");
return $this->db->table('auth_groups_users')
->where([
'user_id' => $userId,
'group_id' => (int) $groupId
])->delete();
}
/**
* Removes a single user from all groups.
*
* #param int $userId
*
* #return bool
*/
public function removeUserFromAllGroups(int $userId)
{
cache()->delete("{$userId}_groups");
cache()->delete("{$userId}_permissions");
return $this->db->table('auth_groups_users')
->where('user_id', (int)$userId)
->delete();
}
/**
* Returns an array of all groups that a user is a member of.
*
* #param int $userId
*
* #return array
*/
public function getGroupsForUser(int $userId)
{
if (null === $found = cache("{$userId}_groups"))
{
$found = $this->builder()
->select('auth_groups_users.*, auth_groups.name, auth_groups.description')
->join('auth_groups_users', 'auth_groups_users.group_id = auth_groups.id', 'left')
->where('user_id', $userId)
->get()->getResultArray();
cache()->save("{$userId}_groups", $found, 300);
}
return $found;
}
/**
* Returns an array of all users that are members of a group.
*
* #param int $groupId
*
* #return array
*/
public function getUsersForGroup(int $groupId)
{
if (null === $found = cache("{$groupId}_users"))
{
$found = $this->builder()
->select('auth_groups_users.*, users.*')
->join('auth_groups_users', 'auth_groups_users.group_id = auth_groups.id', 'left')
->join('users', 'auth_groups_users.user_id = users.id', 'left')
->where('auth_groups.id', $groupId)
->get()->getResultArray();
cache()->save("{$groupId}_users", $found, 300);
}
return $found;
}
//--------------------------------------------------------------------
// Permissions
//--------------------------------------------------------------------
/**
* Gets all permissions for a group in a way that can be
* easily used to check against:
*
* [
* id => name,
* id => name
* ]
*
* #param int $groupId
*
* #return array
*/
public function getPermissionsForGroup(int $groupId): array
{
$permissionModel = model(PermissionModel::class);
$fromGroup = $permissionModel
->select('auth_permissions.*')
->join('auth_groups_permissions', 'auth_groups_permissions.permission_id = auth_permissions.id', 'inner')
->where('group_id', $groupId)
->findAll();
$found = [];
foreach ($fromGroup as $permission)
{
$found[$permission['id']] = $permission;
}
return $found;
}
/**
* Add a single permission to a single group, by IDs.
*
* #param int $permissionId
* #param int $groupId
*
* #return mixed
*/
public function addPermissionToGroup(int $permissionId, int $groupId)
{
$data = [
'permission_id' => (int)$permissionId,
'group_id' => (int)$groupId
];
return $this->db->table('auth_groups_permissions')->insert($data);
}
//--------------------------------------------------------------------
/**
* Removes a single permission from a single group.
*
* #param int $permissionId
* #param int $groupId
*
* #return mixed
*/
public function removePermissionFromGroup(int $permissionId, int $groupId)
{
return $this->db->table('auth_groups_permissions')
->where([
'permission_id' => $permissionId,
'group_id' => $groupId
])->delete();
}
//--------------------------------------------------------------------
/**
* Removes a single permission from all groups.
*
* #param int $permissionId
*
* #return mixed
*/
public function removePermissionFromAllGroups(int $permissionId)
{
return $this->db->table('auth_groups_permissions')
->where('permission_id', $permissionId)
->delete();
}
}
<?php
/*
* Core Auth routes file.
*/
$routes->group('api', ['namespace' => 'Modules\Auth\Controllers'], function ($routes) {
$routes->resource('group', ['filter' => 'authJwt']);
$routes->resource('permission', ['filter' => 'authJwt']);
$routes->resource('groupPermission', ['filter' => 'authJwt']);
$routes->resource('userPermission', ['filter' => 'authJwt']);
$routes->group('auth', function ($routes) {
$routes->post('signin-jwt', 'Auth::signInJwt', ['filter' => 'isSignIn']);
$routes->post('signin', 'Auth::signIn', ['filter' => 'isSignIn']);
$routes->get('signout', 'Auth::signOut', ['filter' => 'authJwt']);
$routes->get('is-signin', 'Auth::isSignIn',['filter' => 'authJwt']);
$routes->post('signup', 'Auth::signUp', ['filter' => 'isSignIn']);
$routes->post('forgot', 'Auth::forgot', ['filter' => 'isSignIn']);
$routes->post('reset-password-email', 'Auth::resetPasswordViaEmail', ['filter' => 'isSignIn']);
$routes->post('reset-password-sms', 'Auth::resetPasswordViaSms', ['filter' => 'isSignIn']);
$routes->post('activate-account-email', 'Auth::activateAccountViaEmail', ['filter' => 'isSignIn']);
$routes->post('send-activate-email', 'Auth::sendActivateCodeViaEmail', ['filter' => 'isSignIn']);
$routes->post('activate-account-sms', 'Auth::activateAccountViaSms', ['filter' => 'isSignIn']);
$routes->post('send-activate-sms', 'Auth::sendActivateCodeViaSms', ['filter' => 'isSignIn']);
});
});

Extending IonAuth model, language files from the third party folder - Codeigniter4

IonAuth is running in the ThirdParty folder on Codeigniter4. I have extended the controller, in that I have Auth.php running in my app/Controllers directory and that is working.
How can I extend the IonAuth library, the model and the language files etc? These files get ignored, unlike the Auth.php controller. I don't want to edit the files in the ThirdParty folder, to make it easier to upgrade etc. Thanks.
look at my code do it like me
follow my approach
ctl auth
<?php namespace Modules\Auth\Controllers;
use Modules\Auth\Config\ModuleAuthConfig;
use Modules\Auth\Config\Services;
use Modules\Auth\Entities\AuthEntity;
use Modules\Auth\Enums\RoleType;
use Modules\Auth\Interfaces\AuthControllerInterface;
use Modules\Shared\Config\ModuleSharedConfig;
use Modules\Shared\Controllers\BaseController;
use Modules\Shared\Enums\NotificationType;
use CodeIgniter\HTTP\ResponseInterface;
use Myth\Auth\AuthTrait;
use Pusher\Pusher;
use ReCaptcha\ReCaptcha;
class Auth extends BaseController implements AuthControllerInterface
{
use AuthTrait;
public function signInJwt(): ResponseInterface
{
/**
* Attempts to verify the user's credentials
* through a POST request.
*/
$rules = [
'login' => 'required',
'password' => 'required'
];
$config = config('Myth\Auth\Config\Auth');
if ($config->validFields == ['email']) {
$rules['login'] .= '|valid_email';
};
if (!$this->validate($rules)) {
return $this->response->setJSON(['error' => $this->validator->getErrors()])
->setStatusCode(ResponseInterface::HTTP_NOT_ACCEPTABLE, lang('Authenticate.auth.validation'))
->setContentType('application/json');
}
$authEntity = new AuthEntity((array)$this->request->getVar());
$authEntity->logInMode()->loginDate()->ipAddress($this->request->getIPAddress());
$authService = Services::authService();
$data = $authService->signInJwt($authEntity);
$authConfig = new ModuleAuthConfig();
return $this->response->setHeader($authConfig->jwt['name'], $data['jwt']['token'])
->setCookie($authConfig->jwt['name'], $data['jwt']['token'], $data['jwt']['expire'])->
setJSON($data)->setStatusCode(ResponseInterface::HTTP_OK, lang('Authenticate.auth.logIn'))
->setContentType('application/json');
}
public function signIn(): ResponseInterface
{
$this->setupAuthClasses();
/**
* Attempts to verify the user's credentials
* through a POST request.
*/
$rules = [
'login' => 'required',
'password' => 'required'
];
$config = config('Myth\Auth\Config\Auth');
if ($config->validFields == ['email']) {
$rules['login'] .= '|valid_email';
};
if (!$this->validate($rules)) {
return $this->response->setJSON(['error' => $this->validator->getErrors()])
->setStatusCode(ResponseInterface::HTTP_NOT_ACCEPTABLE, lang('Authenticate.auth.validation'))
->setContentType('application/json');
}
$authEntity = new AuthEntity((array)$this->request->getVar());
$authEntity->logInMode();
$remember = $authEntity->remember ?? false;
if (!$this->authenticate->attempt([$authEntity->loginType => $authEntity->login, 'password' => $authEntity->password], $remember)) {
return $this->response->setJSON(['error' => $this->authenticate->error(),
])
->setStatusCode(ResponseInterface::HTTP_UNAUTHORIZED, lang('Auth.badAttempt'))
->setContentType('application/json');
}
// Is the user being forced to reset their password?
if ($this->authenticate->user()->force_pass_reset === true) {
// return redirect()->to(route_to('reset-password') . '?token=' . $this->auth->user()->reset_hash)->withCookies();
return $this->response->setJSON(['token' => $this->authenticate->user()->reset_hash])
->setStatusCode(ResponseInterface::HTTP_UNAUTHORIZED, lang('Authenticate.auth.foreResetPassword'))
->setContentType('application/json');
}
$authService = Services::authService();
$data = $authService->signIn($authEntity);
return $this->response->setJSON(
$data
)->setStatusCode(ResponseInterface::HTTP_OK, lang('Authenticate.auth.logIn'))
->setContentType('application/json');
}
/**
* Log the user out.
*/
public function signOut(): ResponseInterface
{
$this->setupAuthClasses();
$authConfig = new ModuleAuthConfig();
$jwtHeader = $this->request->getServer('HTTP_AUTHORIZATION');
$jwtCookie = $this->request->getCookie($authConfig->jwt['name']);
if ($this->authenticate->check()) {
$this->authenticate->logout();
} else if (!is_null($jwtHeader) || !is_null($jwtCookie)) {
$authService = Services::authService();
$requestWithUser = Services::requestWithUser();
$authService->signOutJwt($requestWithUser->getUser());
$this->response->setHeader($authConfig->jwt['name'], '');
$this->response->setCookie($authConfig->jwt['name'], '', 0);
}
return $this->response->setJSON(['success' => true])
->setStatusCode(ResponseInterface::HTTP_OK, lang('Authenticate.auth.logOut'))
->setContentType('application/json');
}
/**
* Log the user out.
*/
public function isSignIn(): ResponseInterface
{
$this->setupAuthClasses();
$requestWithUser = Services::requestWithUser();
if ($this->authenticate->check() || isset($requestWithUser->getUser()->id)) {
return $this->response->setJSON(['success' => true])
->setStatusCode(ResponseInterface::HTTP_OK, lang('check is sign in'))
->setContentType('application/json');
} else {
return $this->response->setJSON(['success' => false,
])
->setStatusCode(ResponseInterface::HTTP_OK, lang('check is sign in'))
->setContentType('application/json');
}
}
//--------------------------------------------------------------------
// Register
//--------------------------------------------------------------------
/**
* Displays the user registration page.
*/
public function signUp(): ResponseInterface
{
$throttler = \Codeigniter\Config\Services::throttler();
if ($throttler->check($this->request->getIPAddress(), 5, MINUTE) === false) {
return $this->response->setJSON(['data' => $throttler->getTokentime()])
->setStatusCode(ResponseInterface::HTTP_TOO_MANY_REQUESTS, lang('Auth.tooManyRequests', [$throttler->getTokentime()]))
->setContentType('application/json');
}
// Validate here first, since some things,
// like the password, can only be validated properly here.
// strong password didint work custom validation strong_password
// password=> strong_password
helper('authentication');
if (loginVia($this->request->getVar('login') ?? $this->request->getVar('login')) == 'email') {
$lineRule = 'required|valid_email|is_unique[users.email]';
} else if (loginVia($this->request->getVar('login') ?? $this->request->getVar('login')) == 'phone') {
$lineRule = 'required|min_length[9]|is_unique[users.phone]';
} else {
return $this->response->setJSON(['error' => lang('Authenticate.auth.emailOrPhone')])
->setStatusCode(ResponseInterface::HTTP_NOT_ACCEPTABLE, lang('Authenticate.auth.validation'))
->setContentType('application/json');
}
$rules = [
'username' => 'required|alpha_numeric_space|min_length[3]|is_unique[users.username]',
'login' => $lineRule,
'password' => 'required|min_length[6]',
'passConfirm' => 'required|matches[password]',
'action' => 'required',
'token' => 'required',
'socialLogin' => 'required'
];
if (!$this->validate($rules)) {
return $this->response->setJSON([
'error' => service('validation')->getErrors(),
])
->setStatusCode(ResponseInterface::HTTP_NOT_ACCEPTABLE, lang('Authenticate.auth.validation'))
->setContentType('application/json');
}
$authConfig = new \Modules\Auth\Config\ModuleAuthConfig();
// ->setExpectedHostname($_SERVER['SERVER_NAME'])
$recaptcha = new ReCaptcha($authConfig->captcha['secretKey']);
$resp = $recaptcha->setExpectedAction($this->request->getVar('action'))
->setScoreThreshold(0.2)
->verify($this->request->getVar('token'), $_SERVER['REMOTE_ADDR']);
// verify the response
if (!$resp->isSuccess() && !$this->request->getVar('socialLogin')) {
// spam submission
// show error message
return $this->response->setJSON([
'error' => $resp->getErrorCodes()])
->setStatusCode(ResponseInterface:: HTTP_UNAUTHORIZED, lang('Authenticate.auth.captchaError'))
->setContentType('application/json');
}
$authEntity = new AuthEntity((array)$this->request->getVar());
$authEntity->logInMode()->createdAt()->setRole(RoleType::Member);
unset($authEntity->token);
unset($authEntity->action);
$authService = Services::authService();
$authService->signUp($authEntity);
$sharedConfig = new ModuleSharedConfig();
$pusher = new Pusher(
$sharedConfig->pusher['authKey'],
$sharedConfig->pusher['secret'],
$sharedConfig->pusher['appId'],
['cluster' => $sharedConfig->pusher['cluster'],
'useTLS' => $sharedConfig->pusher['useTLS']]
);
$data['type'] = NotificationType::NewUser;
$data['message'] = 'new user register';
$data['counter'] = 1;
$data['date'] = date('Y-m-d H:i:s', time());;
$pusher->trigger('notification-channel', 'my-event', $data);
return $this->response->setJSON(['success' => true])
->setStatusCode(ResponseInterface::HTTP_OK, lang('Auth.registerSuccess'))
->setContentType('application/json');
}
//--------------------------------------------------------------------
// Forgot Password
//--------------------------------------------------------------------
/**
* Displays the forgot password form.
*/
public
function forgot(): ResponseInterface
{
$rules = [
'login' => 'required',
'action' => 'required',
'token' => 'required',
];
if (!$this->validate($rules)) {
return $this->response->setJSON(['error' => service('validation')->getErrors()])
->setStatusCode(ResponseInterface::HTTP_NOT_ACCEPTABLE, lang('Authenticate.auth.validation'))
->setContentType('application/json');
}
$authConfig = new \Modules\Auth\Config\ModuleAuthConfig();
// ->setExpectedHostname($_SERVER['SERVER_NAME'])
$recaptcha = new ReCaptcha($authConfig->captcha['secretKey']);
$resp = $recaptcha->setExpectedAction($this->request->getVar('action'))
->setScoreThreshold(0.2)
->verify($this->request->getVar('token'), $_SERVER['REMOTE_ADDR']);
// verify the response
if (!$resp->isSuccess()) {
// spam submission
// show error message
return $this->response->setJSON([
'error' => $resp->getErrorCodes()])
->setStatusCode(ResponseInterface:: HTTP_UNAUTHORIZED, lang('Authenticate.auth.captchaError'))
->setContentType('application/json');
}
$authEntity = new AuthEntity((array)$this->request->getVar());
$authEntity->logInMode(false)->generateResetHash();
unset($authEntity->token);
unset($authEntity->action);
$authService = Services::authService();
$authService->forgot($authEntity);
return $this->response->setJSON(['success' => true])
->setStatusCode(ResponseInterface::HTTP_OK, lang('Authenticate.auth.forgotEmailSmsSent'))
->setContentType('application/json');
}
/**
* Displays the Reset Password form.
*/
/**
* Verifies the code with the email and saves the new password,
* if they all pass validation.
*
* #return mixed
*/
public
function resetPasswordViaSms(): ResponseInterface
{
$rules = [
'code' => 'required',
'phone' => 'required',
'password' => 'required',
'passConfirm' => 'required|matches[password]',
];
if (!$this->validate($rules)) {
return $this->response->setJSON(['error' => $this->validator->getErrors(),])
->setStatusCode(ResponseInterface::HTTP_NOT_ACCEPTABLE, lang('Authenticate.auth.validation'))
->setContentType('application/json');
}
$authEntity = new AuthEntity((array)$this->request->getVar());
$authEntity->resetPassword();
$authService = Services::authService();
$authService->resetPasswordViaSms($authEntity);
return $this->response->setJSON(['success' => true])->setStatusCode(ResponseInterface::HTTP_OK, lang('Auth.resetSuccess'))
->setContentType('application/json');
}
/**
* Verifies the code with the email and saves the new password,
* if they all pass validation.
*
* #return mixed
*/
public
function resetPasswordViaEmail(): ResponseInterface
{
$rules = [
'token' => 'required',
'email' => 'required|valid_email',
'password' => 'required',
'passConfirm' => 'required|matches[password]',
];
if (!$this->validate($rules)) {
return $this->response->setJSON(['error' => $this->validator->getErrors()])
->setStatusCode(ResponseInterface::HTTP_NOT_ACCEPTABLE, lang('Authenticate.auth.validation'))
->setContentType('application/json');
}
$authEntity = new AuthEntity((array)$this->request->getVar());
$authEntity->resetPassword()
->userAgent($this->request->getUserAgent())
->ipAddress($this->request->getIPAddress());
$authService = Services::authService();
$authService->resetPasswordViaEmail($authEntity);
return $this->response->setJSON(['success' => true])->setStatusCode(ResponseInterface::HTTP_OK, lang('Auth.resetSuccess'))
->setContentType('application/json');
}
/**
* Activate account.
*
* #return mixed
*/
public
function activateAccountViaEmail(): ResponseInterface
{
$rules = [
'token' => 'required',
'email' => 'required|valid_email',
];
if (!$this->validate($rules)) {
return $this->response->setJSON([
'error' => $this->validator->getErrors()])
->setStatusCode(ResponseInterface::HTTP_NOT_ACCEPTABLE, lang('Authenticate.auth.validation'))
->setContentType('application/json');
}
$authEntity = new AuthEntity((array)$this->request->getVar());
$authEntity->activate()
->userAgent($this->request->getUserAgent())
->ipAddress($this->request->getIPAddress());
$authService = Services::authService();
$authService->activateAccountViaEmail($authEntity);
return $this->response->setJSON(['success' => true])
->setStatusCode(ResponseInterface::HTTP_OK, lang('Auth.registerSuccess'))
->setContentType('application/json');
}
/**
* Resend activation account.
*
* #return mixed
* #throws \Exception
*/
public
function sendActivateCodeViaEmail(): ResponseInterface
{
$rules = [
'email' => 'required',
];
if (!$this->validate($rules)) {
return $this->response->setJSON(['error' => service('validation')->getErrors()
])
->setStatusCode(ResponseInterface::HTTP_NOT_ACCEPTABLE, lang('Authenticate.auth.validation'))
->setContentType('application/json');
}
$authEntity = new AuthEntity((array)$this->request->getVar());
$authEntity->generateActivateHash();
$authService = Services::authService();
$authService->sendActivateCodeViaEmail($authEntity);
return $this->response->setJSON(['success' => true])
->setStatusCode(ResponseInterface::HTTP_OK, lang('Auth.activationSuccess'))
->setContentType('application/json');
}
/**
* Activate account via sma.
*
* #return mixed
*/
public
function activateAccountViaSms(): ResponseInterface
{
$rules = [
'phone' => 'required',
'code' => 'required',
];
if (!$this->validate($rules)) {
return $this->response->setJSON(['error' => service('validation')->getErrors()])
->setStatusCode(ResponseInterface::HTTP_NOT_ACCEPTABLE, lang('Authenticate.auth.validation'))
->setContentType('application/json');
}
$authEntity = new AuthEntity((array)$this->request->getVar());
$authEntity->activate();
$authService = Services::authService();
$authService->activateAccountViaSms($authEntity);
return $this->response->setJSON(['success' => true])
->setStatusCode(ResponseInterface::HTTP_OK, lang('Authenticate.auth.registerSuccess'))
->setContentType('application/json');
}
/**
* Activate account via sma.
*
* #return mixed
*/
public
function sendActivateCodeViaSms(): ResponseInterface
{
$rules = [
'phone' => 'required',
];
if (!$this->validate($rules)) {
return $this->response->setJSON(['error' => service('validation')->getErrors()])
->setStatusCode(ResponseInterface::HTTP_NOT_ACCEPTABLE, lang('Authenticate.auth.validation'))
->setContentType('application/json');
}
$authEntity = new AuthEntity((array)$this->request->getVar());
$authService = Services::authService();
$authService->sendActivateCodeViaSms($authEntity);
return $this->response->setJSON(['success' => true,
])
->setStatusCode(ResponseInterface::HTTP_OK, lang('Authenticate.auth.smsActivation'))
->setContentType('application/json');
}
}
entity auth
<?php namespace Modules\Auth\Entities;
use \CodeIgniter\Entity;
use CodeIgniter\I18n\Time;
use Myth\Auth\Authorization\GroupModel;
use Myth\Auth\Authorization\PermissionModel;
use Myth\Auth\Entities\User;
use Myth\Auth\Password;
class AuthEntity extends Entity
{
protected $id;
protected $phone;
protected $username;
protected $image;
protected $email;
protected $password;
protected $login;
protected $loginType;
protected $remember;
protected $IpAddress;
protected $userAgent;
protected $role;
protected $code;
protected $token;
protected $action;
protected $attributes = [
'id' => null,
'username' => null,
'phone' => null,
'email' => null,
'active' => null,
'created_at' => null,
'login' => null,
'loginType' => null,
'password' => null,
'ip_address' => null,
'date' => null,
'success' => null,
'role' => null,
'code' => null,
'token' => null,
'user_agent' => null,
'remember' => null,
];
protected $datamap = [
'createdAt' => 'created_at',
'ipAddress' => 'ip_address',
'userAgent' => 'user_agent',
];
/**
* Define properties that are automatically converted to Time instances.
*/
protected $dates = ['reset_at', 'reset_expires', 'created_at', 'updated_at', 'deleted_at'];
/**
* Array of field names and the type of value to cast them as
* when they are accessed.
*/
protected $casts = [
'active' => 'boolean',
'force_pass_reset' => 'boolean',
];
/**
* Per-user permissions cache
* #var array
*/
protected $permissions = [];
/**
* Per-user roles cache
* #var array
*/
protected $roles = [];
/**
* Automatically hashes the password when set.
*
* #see https://paragonie.com/blog/2015/04/secure-authentication-php-with-long-term-persistence
*
* #param string $password
*/
public function setPassword(string $password)
{
$this->attributes['password'] = $password;
$this->attributes['password_hash'] = Password::hash($password);
/*
Set these vars to null in case a reset password was asked.
Scenario:
user (a *dumb* one with short memory) requests a
reset-token and then does nothing => asks the
administrator to reset his password.
User would have a new password but still anyone with the
reset-token would be able to change the password.
*/
$this->attributes['reset_hash'] = null;
$this->attributes['reset_at'] = null;
$this->attributes['reset_expires'] = null;
}
/**
* Force a user to reset their password on next page refresh
* or login. Checked in the LocalAuthenticator's check() method.
*
* #return $this
* #throws \Exception
*
*/
public function forcePasswordReset(): AuthEntity
{
$this->generateResetHash();
$this->attributes['force_pass_reset'] = 1;
return $this;
}
/**
* Generates a secure hash to use for password reset purposes,
* saves it to the instance.
*
* #return $this
* #throws \Exception
*/
public function generateResetHash(): AuthEntity
{
$this->attributes['reset_hash'] = bin2hex(random_bytes(16));
$this->attributes['reset_expires'] = date('Y-m-d H:i:s', time() + config('Auth')->resetTime);
return $this;
}
/**
* Generates a secure random hash to use for account activation.
*
* #return $this
* #throws \Exception
*/
public function generateActivateHash(): AuthEntity
{
$this->attributes['activate_hash'] = bin2hex(random_bytes(16));
return $this;
}
/**
* Activate user.
*
* #return $this
*/
public function activate(): AuthEntity
{
$this->attributes['active'] = 1;
$this->attributes['activate_hash'] = null;
return $this;
}
/**
* Unactivate user.
*
* #return $this
*/
public function deactivate(): AuthEntity
{
$this->attributes['active'] = 0;
return $this;
}
/**
* Checks to see if a user is active.
*
* #return bool
*/
public function isActivated(): bool
{
return isset($this->attributes['active']) && $this->attributes['active'] == true;
}
public function logInMode($flag = true): AuthEntity
{
// Determine credential type
if ($flag == false) {
if (filter_var($this->attributes['login'], FILTER_VALIDATE_EMAIL)) {
$this->attributes['loginType'] = 'email';
} else if (is_numeric($this->attributes['login'])) {
$this->attributes['loginType'] = 'phone';
} else {
$this->attributes['loginType'] = 'username';
}
} else {
if (filter_var($this->attributes['login'], FILTER_VALIDATE_EMAIL)) {
$this->attributes['loginType'] = 'email';
$this->attributes['email'] = $this->attributes['login'];
} else if (is_numeric($this->attributes['login'])) {
$this->attributes['loginType'] = 'phone';
$this->attributes['phone'] = $this->attributes['login'];
} else {
$this->attributes['loginType'] = 'username';
$this->attributes['username'] = $this->attributes['login'];
}
}
return $this;
}
public function ipAddress(string $ip): AuthEntity
{
$this->attributes['ip_address'] = $ip;
return $this;
}
public function loginDate(): AuthEntity
{
$this->attributes['date'] = date('Y-m-d H:i:s', time());;
return $this;
}
public function loginSuccess(bool $flag): AuthEntity
{
$this->attributes['success'] = $flag;
return $this;
}
public function createdAt(): AuthEntity
{
$this->attributes['created_at'] = date('Y-m-d H:i:s', time());;
return $this;
}
public function setRole(string $role): AuthEntity
{
$this->attributes['role'] = $role;
return $this;
}
public function resetPassword(): AuthEntity
{
$this->attributes['reset_hash'] = null;
$this->attributes['reset_expires'] = null;
$this->attributes['reset_at'] = date('Y-m-d H:i:s');
$this->attributes['force_pass_reset'] = false;
return $this;
}
public function userAgent(string $agent): AuthEntity
{
$this->attributes['user_agent'] = $agent;
return $this;
}
}
service auth
<?php namespace Modules\Auth\Services;
use Codeigniter\Config\Services;
use CodeIgniter\Session\SessionInterface;
use Config\Email;
use Modules\Auth\Config\ModuleAuthConfig;
use Modules\Auth\Entities\AuthEntity;
use Modules\Auth\Interfaces\AuthServiceInterface;
use Modules\Auth\Models\GroupsPermissionModel;
use Modules\Auth\Models\UsersPermissionModel;
use Modules\Shared\Config\ModuleSharedConfig;
use Modules\Shared\Libraries\MainService;
use Modules\Shared\Libraries\Sms;
use CodeIgniter\HTTP\ResponseInterface;
use Modules\Auth\Libraries\CsrfSecurity;
use Myth\Auth\Authorization\GroupModel;
use Myth\Auth\Authorization\PermissionModel;
use Myth\Auth\AuthTrait;
use Myth\Auth\Models\LoginModel;
use Myth\Auth\Models\UserModel;
use Myth\Auth\Password;
class AuthService extends MainService implements AuthServiceInterface
{
use AuthTrait;
private CsrfSecurity $csrfSecurity;
private GroupModel $groupModel;
private PermissionModel $permissionModel;
private ModuleAuthConfig $authConfig;
private UserModel $userModel;
private SessionInterface $session;
private LoginModel $loginModel;
private ModuleSharedConfig $sharedConfig;
private Sms $sms;
private GroupsPermissionModel $groupsPermissionModel;
private UsersPermissionModel $usersPermissionModel;
private \CodeIgniter\Email\Email $email;
public function __construct()
{
$this->userModel = new UserModel();
$this->authConfig = new ModuleAuthConfig();
$this->groupModel = new GroupModel();
$this->csrfSecurity = new CsrfSecurity();
$this->permissionModel = new PermissionModel();
$this->loginModel = new LoginModel();
$this->session = \Config\Services::session();
$this->sharedConfig = new ModuleSharedConfig();
$this->sms = new Sms($this->sharedConfig->sms['userName'],
$this->sharedConfig->sms['password'],
0);
$this->groupsPermissionModel = new GroupsPermissionModel();
$this->usersPermissionModel = new UsersPermissionModel();
$this->email = Services::email();
$emailConfig = new Email();
$this->email->initialize($emailConfig)->
setFrom($emailConfig->fromEmail, getenv('siteAddress'));
}
public function signInJwt(AuthEntity $entity): array
{
if (is_null($entity)) $this->httpException(lang('Shared.api.validation'), ResponseInterface::HTTP_CONFLICT);
$findUser = $this->userModel->asObject()->where($entity->loginType, $entity->login)->first();
if (!$findUser) {
$entity->loginSuccess(false);
$this->loginModel->save($entity);
$this->httpException(lang('Authenticate.auth.accountNotExist'), ResponseInterface::HTTP_CONFLICT);
}
if ($findUser->active == false) {
$entity->loginSuccess(false);
$this->loginModel->save($entity);
$this->httpException(lang('Authenticate.auth.accountNotActive'), ResponseInterface::HTTP_CONFLICT);
}
if ($findUser->status == true) {
$entity->loginSuccess(false);
$this->loginModel->save($entity);
$this->httpException(lang('Authenticate.auth.accountIsBand'), ResponseInterface::HTTP_CONFLICT);
}
if (!Password::verify($entity->password, $findUser->password_hash)) {
$entity->loginSuccess(false);
$this->loginModel->save($entity);
$this->httpException(lang('Authenticate.auth.accountNotExist'), ResponseInterface::HTTP_CONFLICT);
}
$entity->loginSuccess(true);
$this->loginModel->save($entity);
$role = $this->groupModel->asObject()->getGroupsForUser($findUser->id);
$permissions = $this->permissionModel->asObject()->where('active', '1')->findAll();
$permissionUser = $this->usersPermissionModel->permissionsOfUser($findUser->id);
$permissionGroup = $this->groupsPermissionModel->permissionsOfGroup($role[0]['group_id']);
helper('jwt');
$timeJwt = isset($entity->remember) ? timeJwt(true) : timeJwt(false);
$jwtToken = generateJWT($findUser->id, $timeJwt['init'], $timeJwt['expire'], $this->authConfig->jwt['secretKey']);
$data = [
'success' => true,
'role' => [
'name' => $role[0]['name'],
'id' => $role[0]['group_id']
],
'permissions' => $permissions,
'permissionUser' => $permissionUser,
'permissionGroup' => $permissionGroup,
'userInformation' => [
'id' => $findUser->id,
'userName' => $findUser->username,
'image' => $findUser->image,
'firstName' => $findUser->first_name,
'lastName' => $findUser->last_name,
'email' => $findUser->email,
'phone' => $findUser->phone,
],
'csrf' => $this->csrfSecurity->init(),
'jwt' => [
"token" => $jwtToken,
"expire" => $timeJwt['expire'],
],
];
return $data;
}
public function signIn(AuthEntity $entity): array
{
if (is_null($entity)) $this->httpException(lang('Shared.api.validation'), ResponseInterface::HTTP_CONFLICT);
helper('cookie');
//
$findUser = $this->userModel->asObject()->where($entity->loginType, $entity->login)->first();
$role = $this->groupModel->asObject()->getGroupsForUser($findUser->id);
$permissions = $this->permissionModel->asObject()->where('active', '1')->findAll();
$permissionUser = $this->usersPermissionModel->permissionsOfUser($findUser->id);
$permissionGroup = $this->groupsPermissionModel->permissionsOfGroup($findUser->id);
// store user inof in session
// $this->session->set('userInformation', [
// 'userName' => $this->authenticate->user()->username,
// 'image' => $this->authenticate->user()->image,
// 'firstName' => $this->authenticate->user()->first_name,
// 'lastName' => $this->authenticate->user()->last_name,
// 'email' => $this->authenticate->user()->email,
// 'phone' => $this->authenticate->user()->phone,
// ]);
$data = [
'success' => true,
'role' => [
'name' => $role[0]['name'],
'id' => $role[0]['group_id']
],
'permissions' => $permissions,
'permissionUser' => $permissionUser,
'permissionGroup' => $permissionGroup,
'userInformation' => [
'id' => $findUser->id,
'userName' => $findUser->username,
'image' => $findUser->image,
'firstName' => $findUser->first_name,
'lastName' => $findUser->last_name,
'email' => $findUser->email,
'phone' => $findUser->phone,
],
'csrf' => $this->csrfSecurity->init(),
];
return $data;
}
/**
* Log the user out.
* #param object $userData
*/
public function signOutJwt(object $userData): void
{
if (!isset($userData->id)) $this->httpException(lang('Authenticate.filter.jwt'), ResponseInterface::HTTP_CONFLICT);
$findUser = $this->userModel->asObject()->where("id", $userData->id)->first();
if (is_null($findUser)) $this->httpException(lang('Auth.forgotNoUser'), ResponseInterface::HTTP_UNAUTHORIZED);
}
//--------------------------------------------------------------------
// Register
//--------------------------------------------------------------------
/**
* Displays the user registration page.
* #param AuthEntity $entity
*/
public function signUp(AuthEntity $entity): void
{
if (is_null($entity)) $this->httpException(lang('Shared.api.validation'), ResponseInterface::HTTP_CONFLICT);
$entity->generateActivateHash();
$this->userModel->withGroup($entity->role);
if (!$this->userModel->save($entity)) {
$message = lang('Authenticate.auth.rejectRegistration') . " , " . serializeMessages($this->userModel->errors());
$this->httpException($message, ResponseInterface::HTTP_BAD_REQUEST);
}
if ($entity->loginType == 'email') {
$isSent = $this->email
->setTo($entity->email)
->setSubject(lang('Auth.activationSubject'))
->setMessage(view($this->authConfig->views['emailActivation'],
['hash' => $entity->toArray()['activate_hash']]))
->setMailType('html')->send();
if (!$isSent) {
$this->groupModel->removeUserFromAllGroups($this->userModel->getInsertID());
$this->userModel->where('id', $this->userModel->getInsertID())->delete();
$message = lang('Authenticate.auth.failRegistration') . " , " . serializeMessages($this->activator->error() ?? lang('Auth.unknownError'));
$this->httpException($message,
ResponseInterface::HTTP_BAD_REQUEST, $this->email->printDebugger(['headers']));
}
} else if ($entity->loginType == 'phone') {
$isSend = $this->sms->sendActivationCode($entity->phone, getenv('siteAddress'));
if ($isSend < 2000) {
$message = lang('Authenticate.auth.smsSendFail');
$this->httpException($message, ResponseInterface::HTTP_FOUND);
}
}
}
//--------------------------------------------------------------------
// Forgot Password
//--------------------------------------------------------------------
/**
* Displays the forgot password form.
* #param AuthEntity $entity
*/
public
function forgot(AuthEntity $entity): void
{
if (is_null($entity)) $this->httpException(lang('Shared.api.validation'), ResponseInterface::HTTP_CONFLICT);
$findUser = $this->userModel->where($entity->loginType, $entity->login)->first();
if (is_null($findUser)) $this->httpException(lang('Auth.forgotNoUser'), ResponseInterface::HTTP_UNAUTHORIZED);
$statusEmail = false;
$statusSms = 0;
if (!is_null($findUser->email)) {
$statusEmail = $this->email
->setTo($findUser->email)
->setSubject(lang('Auth.forgotSubject'))
->setMessage(view($this->authConfig->views['emailForgot'],
['hash' => $entity->toArray()['reset_hash']]))
->setMailType('html')->send();
}
if (!is_null($findUser->phone)) {
$statusSms = $this->sms->sendActivationCode($findUser->phone, getenv('siteAddress'));
}
if ($statusSms < 2000 && !$statusEmail) $this->httpException(lang('Auth.unknownError'),
ResponseInterface::HTTP_BAD_REQUEST, $this->email->printDebugger(['headers']));
if (!$this->userModel->update($findUser->id, $entity)) {
$this->httpException(lang('Shared.api.reject'), ResponseInterface::HTTP_BAD_REQUEST, serializeMessages($this->userModel->errors()));
}
}
/**
* Verifies the code with the email and saves the new password,
* if they all pass validation.
*
* #param AuthEntity $entity
*/
public
function resetPasswordViaSms(AuthEntity $entity): void
{
if (is_null($entity)) $this->httpException(lang('Shared.api.validation'), ResponseInterface::HTTP_NOT_ACCEPTABLE);
$findUser = $this->userModel->where('phone', $entity->phone)->first();;
if (is_null($findUser)) $this->httpException(lang('Authenticate.forgotNoUserPhone'), ResponseInterface::HTTP_CONFLICT);
if (!$this->sms->isActivationCodeValid($entity->phone, $entity->code)) $this->httpException(lang('Auth.resetTokenExpired'), ResponseInterface::HTTP_NOT_ACCEPTABLE);
unset($entity->phone);
if (!$this->userModel->update($findUser->id, $entity)) {
$this->httpException(lang('Shared.api.reject'), ResponseInterface::HTTP_BAD_REQUEST, serializeMessages($this->userModel->errors()));
}
}
/**
* Verifies the code with the email and saves the new password,
* if they all pass validation.
*
* #param AuthEntity $entity
*/
public
function resetPasswordViaEmail(AuthEntity $entity): void
{
if (is_null($entity)) $this->httpException(lang('Shared.api.validation'), ResponseInterface::HTTP_NOT_ACCEPTABLE);
$this->userModel->logResetAttempt(
$entity->email,
$entity->token,
$entity->ip_address,
$entity->user_agent
);
$findUser = $this->userModel->where('email', $entity->email)
->where('reset_hash', $entity->token)->first();
if (is_null($findUser)) $this->httpException(lang('Auth.forgotNoUser'), ResponseInterface::HTTP_CONFLICT);
// Reset token still valid?
if (!empty($findUser->reset_expires) && time() > $findUser->reset_expires->getTimestamp()) $this->httpException(lang('Auth.resetTokenExpired'), ResponseInterface::HTTP_NOT_ACCEPTABLE);
unset($entity->email);
if (!$this->userModel->update($findUser->id, $entity)) {
$this->httpException(lang('Shared.api.reject'), ResponseInterface::HTTP_BAD_REQUEST, serializeMessages($this->userModel->errors()));
}
}
/**
* Activate account.
*
* #param AuthEntity $entity
*/
public
function activateAccountViaEmail(AuthEntity $entity): void
{
if (is_null($entity)) $this->httpException(lang('Shared.api.validation'), ResponseInterface::HTTP_NOT_ACCEPTABLE);
$this->userModel->logActivationAttempt(
$entity->token,
$entity->ip_address,
$entity->user_agent
);
$findUser = $this->userModel->where('activate_hash', $entity->token)
->where('active', 0)->where('email', $entity->email)
->first();
if (is_null($findUser)) $this->httpException(lang('Auth.activationNoUser'), ResponseInterface::HTTP_CONFLICT);
unset($entity->email);
if (!$this->userModel->update($findUser->id, $entity)) {
$this->httpException(lang('Shared.api.reject'), ResponseInterface::HTTP_BAD_REQUEST, serializeMessages($this->userModel->errors()));
}
}
/**
* Resend activation account.
* #param AuthEntity $entity
*/
public
function sendActivateCodeViaEmail(AuthEntity $entity): void
{
if (is_null($entity)) $this->httpException(lang('Shared.api.validation'), ResponseInterface::HTTP_NOT_ACCEPTABLE);
$findUser = $this->userModel->where('email', $entity->email)
->where('active', 0)
->first();
if (is_null($findUser)) $this->httpException(lang('Auth.activationNoUser'), ResponseInterface::HTTP_CONFLICT);
$isSent = $this->email
->setTo($entity->email)
->setSubject(lang('Auth.activationSubject'))
->setMessage(view($this->authConfig->views['emailActivation'],
['hash' => $entity->toArray()['activate_hash']]))
->setMailType('html')->send();
if (!$isSent) {
$this->httpException(lang('Auth.unknownError'),
ResponseInterface::HTTP_BAD_REQUEST, $this->email->printDebugger(['headers']['headers'] ?? lang('Auth.unknownError')));
}
unset($entity->email);
if (!$this->userModel->update($findUser->id, $entity)) {
$this->httpException(lang('Shared.api.reject'), ResponseInterface::HTTP_BAD_REQUEST, serializeMessages($this->userModel->errors()));
}
}
/**
* Activate account via sma.
*
* #param AuthEntity $entity
*/
public function activateAccountViaSms(AuthEntity $entity): void
{
if (is_null($entity)) $this->httpException(lang('Shared.api.validation'), ResponseInterface::HTTP_NOT_ACCEPTABLE);
$result = $this->sms->isActivationCodeValid($entity->phone,
$entity->code);
if ($result == false) $this->httpException(lang('Authenticate.auth.smsActivationFail'), ResponseInterface::HTTP_CONFLICT);
$findUser = $this->userModel->where('active', 0)
->where('phone', $entity->phone)->first();
if (is_null($findUser)) $this->httpException(lang('Auth.activationNoUser'), ResponseInterface::HTTP_CONFLICT);
unset($entity->phone);
if (!$this->userModel->update($findUser->id, $entity)) {
$this->httpException(lang('Shared.api.reject'), ResponseInterface::HTTP_BAD_REQUEST, serializeMessages($this->userModel->errors()));
}
}
/**
* Activate account via sma.
*
* #param AuthEntity $entity
*/
public
function sendActivateCodeViaSms(AuthEntity $entity): void
{
if (is_null($entity)) $this->httpException(lang('Shared.api.validation'), ResponseInterface::HTTP_NOT_ACCEPTABLE);
$findUser = $this->userModel
->where('active', 0)->where('phone', $entity->phone)->first();
if (is_null($findUser)) $this->httpException(lang('Auth.activationNoUser'), ResponseInterface::HTTP_CONFLICT);
$result = $this->sms->sendActivationCode($entity->phone, getenv('siteAddress'));
if ($result < 2000) $this->httpException(lang('Authenticate.auth.smsSendFail'), ResponseInterface::HTTP_BAD_REQUEST);
}
}

How to store user details after paypal payment approval?

I'm building an online courses website, where students can buy a course via PayPal. The payment process is working successfully, But I'm confused on where or how to store course and user data after PayPal Payment Approval.
I have a users table, courses table and pivot table: course_students where I store the id of the course and the id of the student:
-------------
course_students
--------------
student_id course_id
1 2
----------
This is PayPalService Class:
class PayPalService
{
use ConsumesExternalServices;
protected $baseUri;
protected $clientId;
protected $clientSecret;
public function __construct()
{
$this->baseUri = config('services.paypal.base_uri');
$this->clientId = config('services.paypal.client_id');
$this->clientSecret = config('services.paypal.client_secret');
}
public function resolveAuthorization(&$queryParams, &$formParams, &$headers)
{
$headers['Authorization'] = $this->resolveAccessToken();
}
public function decodeResponse($response)
{
return json_decode($response);
}
public function resolveAccessToken()
{
$credentials = base64_encode("{$this->clientId}:{$this->clientSecret}");
return "Basic {$credentials}";
}
public function handlePayment(Request $request)
{
$order = $this->createOrder($request->value, $request->currency);
$orderLinks = collect($order->links);
$approve = $orderLinks->where('rel', 'approve')->first();
session()->put('approvalId', $order->id);
return redirect($approve->href);
}
public function handleApproval()
{
if (session()->has('approvalId')) {
$approvalId = session()->get('approvalId');
$payment = $this->capturePayment($approvalId);
$name = $payment->payer->name->given_name;
$payment = $payment->purchase_units[0]->payments->captures[0]->amount;
$amount = $payment->value;
$currency = $payment->currency_code;
return redirect()
->route('success')
->with('payment', "Thanks, {$name}. We received your {$amount}{$currency} payment.");
}
// $errorMessage = 'We cannot capture the payment. Try again, please';
return redirect()
->route('paymentform')
->with('error','We cannot capture the payment. Try again, please');
}
public function createOrder($value, $currency)
{
return $this->makeRequest(
'POST',
'/v2/checkout/orders',
[],
[
'intent' => 'CAPTURE',
'purchase_units' => [
0 => [
'amount' => [
'currency_code' =>strtoupper($currency),
'value' => round($value * $factor = $this->resolveFactor($currency)) / $factor,
]
]
],
'application_context' => [
'brand_name' => config('app.name'),
'shipping_preference' => 'NO_SHIPPING',
'user_action' => 'PAY_NOW',
'return_url' => route('approval'),
'cancel_url' => route('cancelled'),
]
],
[],
$isJsonRequest = true,
);
}
public function capturePayment($approvalId)
{
return $this->makeRequest(
'POST',
"/v2/checkout/orders/{$approvalId}/capture",
[],
[],
[
'Content-Type' => 'application/json'
],
);
}
public function resolveFactor($currency)
{
$zeroDecimalCurrencies = ['JPY'];
if (in_array(strtoupper($currency), $zeroDecimalCurrencies)) {
return 1;
}
return 100;
}
}
PaymentController:
public function paymentForm($course_uuid)
{
$currencies = Currency::all();
$platforms = PaymentPlatform::get();
$course = Course::where('uuid', $course_uuid)->where('status',1)->where('availability',1)->first();
return view('public.payment.paypalform', compact('currencies','platforms','course'));
}
/**
* implment Payemnt process
*
* #param Request $request
*/
public function pay(Request $request)
{
// dd($request->all());
$rules = [
'value' => ['required', 'numeric', 'min:5'],
'currency' => ['required', 'exists:currencies,iso'],
'payment_platform' => ['required', 'exists:payment_platforms,id'],
];
$request->validate($rules);
$paymentPlatform = $this->paymentPlatformResolver
->resolveService($request->payment_platform);
session()->put('paymentPlatformId', $request->payment_platform);
return $paymentPlatform->handlePayment($request);
}
protected function approval()
{
if (session()->has('paymentPlatformId')) {
$paymentPlatform = $this->paymentPlatformResolver
->resolveService(session()->get('paymentPlatformId'));
return $paymentPlatform->handleApproval();
}else{
return redirect()
->route('courses.levels')
->withErrors('We cannot retrieve your payment platform. Try again, please.');
}
}
protected function canceled()
{
return redirect()
->route('courses.levels')
->withErrors('You cancelled the payment.');
}
In your payment controller you can save you the course information in session. After payment when user will redirect, save the information to your desired database table..
//save course info or other info
session()->put('courseInfo', [your data]);
your controller function:
/**
* implment Payemnt process
*
* #param Request $request
*/
public function pay(Request $request)
{
// dd($request->all());
$rules = [
'value' => ['required', 'numeric', 'min:5'],
'currency' => ['required', 'exists:currencies,iso'],
'payment_platform' => ['required', 'exists:payment_platforms,id'],
];
$request->validate($rules);
$paymentPlatform = $this->paymentPlatformResolver
->resolveService($request->payment_platform);
session()->put('paymentPlatformId', $request->payment_platform);
//save course info or other info
session()->put('courseInfo', [your data]);
return $paymentPlatform->handlePayment($request);
}
you another function: approval() call another function $paymentPlatform->handleApproval(); inside of it after payment done.
Go to handleApproval() function and hopefully you will find there user account creation codes. Now get the session value session()->get('courseInfo') and save in your desired table.

Yii2 rest api with bearer auth

I created the api structure/config and it works but now i need to set it up with bearer authentication and every GET request i send to the api (with Authentication Bearer XXXXXXXXXXXX) gives me a 401 error:
{"name":"Unauthorized","message":"Your request was made with invalid credentials.","code":0,"status":401,"type":"yii\\web\\UnauthorizedHttpException"}
Sorry about the length of this question with all snippets but i tried several changes, read all what i found here about this with no success and im starting to lose control on this. What could i be missing?
My app uses the advanced template with the next folder structure (the same as in all howtos ive read):
> -api
> --config
> --main.php
> --params.php
> --modules
> --v1
> --controllers
> --OrdersController.php
> --models
> --Orders.php
> --Module.php
> --web
> --index.php
> -backend
> -common
> -frontend...
api/config/main.php
<?php
$params = array_merge(
require(__DIR__ . '/../../common/config/params.php'),
require(__DIR__ . '/../../common/config/params-local.php'),
require(__DIR__ . '/params.php')
//require(__DIR__ . '/params-local.php')
);
return [
'id' => 'app-api',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'modules' => [
'v1' => [
'basePath' => '#app/modules/v1',
'class' => 'api\modules\v1\Module'
]
],
'components' => [
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => false,
'enableSession' => false,
'loginUrl' =>'',
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'v1/countries',
'tokens' => [
'{id}' => '<id:\\w+>'
]
],
[
'class' => 'yii\rest\UrlRule',
'controller' => 'v1/orders',
'tokens' => [
'{id}' => '<id:\\w+>'
]
]
],
]
],
'params' => $params,
];
api/config/params.php
<?php
return [
'adminEmail' => 'admin#domain.com',
];
api/modules/v1/Module.php
<?php
namespace api\modules\v1;
class Module extends \yii\base\Module
{
public $controllerNamespace = 'api\modules\v1\controllers';
public function init()
{
parent::init();
\Yii::$app->user->enableSession = false;
}
}
api/modules/v1/controllers/OrdersController.php
<?php
namespace api\modules\v1\controllers;
use yii\rest\ActiveController;
use yii\web\Response;
use yii\filters\auth\CompositeAuth;
use yii\filters\auth\HttpBasicAuth;
use yii\filters\auth\HttpBearerAuth;
use yii\filters\auth\QueryParamAuth;
class OrdersController extends ActiveController
{
public $modelClass = 'api\modules\v1\models\Orders';
public function actions() // Just read only rest api
{
$actions = parent::actions();
unset($actions['delete'], $actions['create'], $actions['update']);
return $actions;
}
public function behaviors() {
$behaviors = parent::behaviors();
$behaviors['contentNegotiator']['formats']['text/html'] = Response::FORMAT_JSON;
$behaviors['authenticator'] = [
//'class' => HttpBasicAuth::className(),
'class' => HttpBearerAuth::className(),
//'class' => QueryParamAuth::className(),
];
return $behaviors;
}
}
common/models/User.php
<?php
namespace common\models;
use Yii;
use yii\base\NotSupportedException;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
/**
* User model
*
* #property integer $id
* #property string $username
* #property string $password_hash
* #property string $password_reset_token
* #property string $email
* #property string $auth_key
* #property integer $status
* #property integer $created_at
* #property integer $updated_at
* #property string $password write-only password
*/
class User extends ActiveRecord implements IdentityInterface
{
const STATUS_DELETED = 0;
const STATUS_ACTIVE = 10;
/**
* #inheritdoc
*/
public static function tableName()
{
return '{{%user}}';
}
/**
* #inheritdoc
*/
public function behaviors()
{
return [
TimestampBehavior::className(),
];
}
/**
* #inheritdoc
*/
public function rules()
{
return [
['status', 'default', 'value' => self::STATUS_ACTIVE],
['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],
];
}
/**
* #inheritdoc
*/
public static function findIdentity($id)
{
return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
}
/**
* #inheritdoc
*/
public static function findIdentityByAccessToken($token, $type = null)
{
//throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
return static::findOne(['auth_key' => $token]);
}
/**
* Finds user by username
*
* #param string $username
* #return static|null
*/
public static function findByUsername($username)
{
return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);
}
/**
* Finds user by password reset token
*
* #param string $token password reset token
* #return static|null
*/
public static function findByPasswordResetToken($token)
{
if (!static::isPasswordResetTokenValid($token)) {
return null;
}
return static::findOne([
'password_reset_token' => $token,
'status' => self::STATUS_ACTIVE,
]);
}
/**
* Finds out if password reset token is valid
*
* #param string $token password reset token
* #return boolean
*/
public static function isPasswordResetTokenValid($token)
{
if (empty($token)) {
return false;
}
$timestamp = (int) substr($token, strrpos($token, '_') + 1);
$expire = Yii::$app->params['user.passwordResetTokenExpire'];
return $timestamp + $expire >= time();
}
/**
* #inheritdoc
*/
public function getId()
{
return $this->getPrimaryKey();
}
/**
* #inheritdoc
*/
public function getAuthKey()
{
return $this->auth_key;
}
/**
* #inheritdoc
*/
public function validateAuthKey($authKey)
{
return $this->getAuthKey() === $authKey;
}
/**
* Validates password
*
* #param string $password password to validate
* #return boolean if password provided is valid for current user
*/
public function validatePassword($password)
{
return Yii::$app->security->validatePassword($password, $this->password_hash);
}
/**
* Generates password hash from password and sets it to the model
*
* #param string $password
*/
public function setPassword($password)
{
$this->password_hash = Yii::$app->security->generatePasswordHash($password);
}
/**
* Generates "remember me" authentication key
*/
public function generateAuthKey()
{
$this->auth_key = Yii::$app->security->generateRandomString();
}
/**
* Generates new password reset token
*/
public function generatePasswordResetToken()
{
$this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();
}
/**
* Removes password reset token
*/
public function removePasswordResetToken()
{
$this->password_reset_token = null;
}
}
Thank you in advance,
After checking this question i was able to find what was happening. Just added
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
to api/web/.htaccess and it works
Is this the best approach?

PHP laravel auth with my custom fields

I have seen tutorial on how to uses the default authentication mechanism of laravel.
I want to make my authentication to work for different parameters.
I have following to store in the controller which is for registration of an user:
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'username' => 'required|max:255',
'email' => 'required',
'password' => 'required|alphaNum|min:6',
]);
if ($validator->fails()) {
return redirect('/register')
->withInput()
->withErrors($validator);
}
$confirmation=$this->createConfirmation_code();
$user = new User;
$user->first_name = $request->first_name;
$user->last_name = $request->last_name;
$user->username = $request->username;
$user->email = $request->email;
$user->password = -$request->password;
$user->country = $request->country;
$user->street = $request->street;
$user->zip = $request->zip;
$user->state = $request->state;
$user->city = $request->city;
$user->state = $request->city_state;
$user->institute = $request->institute;
$user->confirmation_code=$confirmation;
$user->confirmed='no';
$this->sendEmailReminder($request,$user);
User::create([
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'username' =>$user->username,
'email' =>$user->email,
'password' => bcrypt($user->password),
'country' =>$user->country,
'street' =>$user->street,
'zip' => $user->zip,
'state' =>$user->state,
'institute' =>$user->institute,
'confirmation_code' =>$user->confirmation_code,
'confirmed' => $user->confirmed
]);
return redirect('/confirm')->with('user',$user);
}
Then for login I an using the following:
public function login(Request $request)
{
$rules = array(
'username' => 'required',
'password' => 'required'
);
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return Redirect::to('/login')
->withErrors($validator);
} else {
$userdata = array(
'username' => $request->username,
'password' => $request->password
);
// attempt to do the login
if (Auth::attempt($userdata)) {
return redirect('/{username}');
} else {
return Redirect::to('/login');
}
}
}
But my login is being failed.
Here is the handle in my Authenticate class:
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->guest()) {
if ($request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
} else {
}
}
return $next($request);
}
This is my User model:
class User extends Authenticatable
{
protected $fillable = [
'first_name', 'last_name','username','email','password','country','street','zip','state','institute','confirmation_code','confirmed'
];
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password');
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Get the e-mail address where password reminders are sent.
*
* #return string
*/
public function getReminderEmail()
{
return $this->email;
}
public function getRememberToken()
{
return $this->remember_token;
}
public function setRememberToken($value)
{
$this->remember_token = $value;
}
public function getRememberTokenName()
{
return 'remember_token';
}
}
And I have not made any change to the default auth.php file. Can anyone help me how can i make it work?

Categories