Laravel custom auth based on json data - laravel

I am trying to make auth based on third party api in laravel. not storing or using data from my local db. Here I am keeping api response data as an array just for visualization . It shows error Argument 1 passed to Illuminate\Auth\SessionGuard::login() must be an instance of Illuminate\Contracts\Auth\Authenticatable, string given, called in vendor\laravel\framework\src\Illuminate\Auth\AuthManager.php . How can I fix that. I also made R&D on it. Thanks in advance
$user = [
'status' => '200',
'token' => 'aWsIpvOEZfv4sfSRUGS2dDeGw7',
'id' => '12454545412',
'user' => [
'name' => 'xyz',
'email' => 'xyz#gmail.com',
'phone' => '12344787',
],
];
$user = json_encode($user);
Auth::login($user);
return redirect( '/home' );

You should create User class as a dummy model if you prefer.
namespace App\Helpers; // depends on you
use Illuminate\Foundation\Auth\User as Authenticatable;
class AuthUser extends Authenticatable
{
protected $guarded = [];
}
And you can use like this:
$user = [
'id' => '12454545412',
'name' => 'xyz',
'email' => 'xyz#gmail.com',
'phone' => 1234564897,
'token' => 'aWsIpvOEZfv4sfSRUGS2dDeGw7' // if you need in your user Object
];
$user = new AuthUser($user);
Auth::login($user);
dd(auth()->user());

Related

Can't proceed to checkout - Call to a member function checkout() on null

I'm trying to charge a customer in my Laravel app but it keeps saying $customer is null. Any idea what's wrong?
The error:
Call to a member function checkout() on null refers to this line return $customer->checkout...
However calling echo $id returns the customer ID so I see no issue why findBillable returns a null object.
The customer does indeed exist in Stripe and hard-coding the ID doesn't change anything.
use Laravel\Cashier\Cashier;
$user = new App\Competitor();
$stripeCustomer = $user->createAsStripeCustomer([
'name' => $request->name,
'email' => $request->email,
'phone' => $request->phone,
]);
$id = $user->stripeId();
$customer = Cashier::findBillable($id);
return $customer->checkout(['price_foobarfoobar' => 1], [
'success_url' => 'https://staging.domain.com/thank-you',
'cancel_url' => 'https://staging.domain.com/sign-up',
]);
Competitor.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Laravel\Cashier\Billable;
class Competitor extends Model
{
use Billable;
protected $table = 'competitors';
protected $fillable = [
'name',
'email',
'phone',
'selected_event',
'team_name',
'user_agent',
'ip_address',
'created_at',
'stripe_transaction',
'stripe_id',
];
}
Had to inform Cashier I was using a different Billable model...
Cashier::useCustomerModel(Competitor::class);

Laravel - Hash input using SHA512

I am creating an API POST request, but I want to hash some of the user input (referenceID and phone_no) and save into hash field using SHA512. I want to put it in the Controller.
I have create the Model Class and also the Controller
Model
protected $fillable = [
'referenceID' ,
'phone_no',
'hash'
];
Controller
public function store(Request $request)
{
$request->validate([
'referenceID' => 'required',
'phone_no' => 'required',
'hash' => 'required'
]);
$valrequest = Task::create($request->all());
return response()->json([
'message' => 'Great success! New validation request created',
'valrequest' => $valrequest, 201
]);
}
I want to hash the user input (referenceID and phone_no) and save into the hash field using SHA512. I want to put it in the Controller. How do I do this.
Should work fine like this, but the code's not tested at all and there's like a million different ways to do this. You won't need to validate the hash because it's no user input.
public function store(Request $request)
{
$request->validate([
'referenceID' => 'required',
'phone_no' => 'required',
]);
$referenceID = $request->referenceID;
$phone_no = $request->phone_no;
$hash = hash('sha512', $referenceID . $phone_no);
$valrequest = Task::create(compact('referenceID', 'phone_no', 'hash'));
return response()->json([
'message' => 'Great success! New validation request created',
'valrequest' => $valrequest, 201
]);
}
Laravel hash provides Bcrypt and Argon2 hashing. If you want to use sha512 you should use php hashing function. hash("sha512","your string");

Laravel Passport Register the user credentials were incorrect

I set up Laravel Passport and currently I am trying to register user with a Post Route. I did create a RegisterController inside Controllers/Api/Auth.
Thus I created a clients table which looks excatly like a users table.
The client gets created if I call the route, but I do not get an access token nor a refresh token.
The route to my controller looks like this (routes/api):
Route::post('register', ['as' => 'register', 'uses' => 'Api\Auth\RegisterController#register']);
My Controller looks like this:
<?php
namespace App\Http\Controllers\Api\Auth;
use App\Client;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Route;
use Laravel\Passport\Client as PClient;
use Illuminate\Http\Request;
class RegisterController extends Controller
{
private $client;
public function __construct() {
$this->client = PClient::find(1);
}
public function register(Request $request)
{
$this->validate($request, [
'name' => 'required',
'email' => 'required|email|unique:users,email',
'password' => 'required|min:6|confirmed'
]);
$client_user = Client::create([
'name' => request('name'),
'email' => request('email'),
'password' => bcrypt(request('password'))
]);
$params = [
'grant_type' => 'password',
'client_id' => $this->client->id,
'client_secret' => $this->client->secret,
'username' => request('email'),
'password' => request('password'),
'scope' => '*'
];
$request->request->add($params);
$proxy = Request::create('oauth/token', 'POST');
return Route::dispatch($proxy);
}
}
This is my Client Model:
class Client extends Model implements AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword, HasApiTokens, Notifiable;
protected $table = 'clients';
protected $fillable = ['name', 'email', 'password'];
protected $hidden = ['password', 'remember_token'];
When I am trying to call it with Postman I get this error message:
I may be way off basis here but it looks as if you are creating your client with a password of "password" due to your bcrypt('password') call.
Should it not be bcrypt(request('password'))?
This would explain why your credentials are wrong in your request, because they are ; )
Ok I fixed it, the post route worked if I used the User Model instead of my Client model, so I guessed that there has to be something different.
After some research I have found out that one needs to add the model, in my case the client model to the providers array inside config/auth.php.
So first one needs to change the api guard like this:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'clients',
],
],
This way to api routes login and register only take action with my clients.
Now you need to a a new provider in this case a clients provider like this.
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'clients' => [
'driver' => 'eloquent',
'model' => App\Client::class
],
],
And voila I get an access token + refresh token if I call the route.

Testing a controller method that uses related models in laravel

I am working in laravel-lumen. I have two models. An Organization model and an Apikey model corresponding to an organizations and an apikeys table. The column organization_id in the apikeys table is a foreign key referring to the id field of the organizations table.
The model for organizations looks like
<?php
namespace App;
use App\Apikey
use Illuminate\Database\Eloquent\Model;
Class Organization Extends Model {
public $table = 'organizations';
public $fillable = [
'name',
'contact_name',
'contact_phone',
'contact_email',
'address1',
'state',
'city',
'zip',
'country'
];
public function apikeys()
{
return $this->hasMany('App\Apikey');
}
}
The apikeys model looks like this
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
Class Apikey Extends Model {
public $table = 'apikeys';
public $fillable = [
'key',
'secret',
'organization_id',
'permissions'
];
}
organization_id in apikeys is a foreign key in the organizations table that refers to the id field of organizations table.
Now I have a controller that generates the api key given an organization_id and the permissions and fills the apikeys table. It looks like this
<?php
use App\Http\Controllers\Controller;
use App\Apikey;
use Illuminate\Http\Request;
public function generateApiKeyGivenOrganizationId(Request $request)
{
$data = $request->all();
// code for generating api key.
$dd = [
'key' => 'generated encrypted key',
'secret' => 'secret',
'organization_id' => $data['organization_id'],
'permissions' => $data['permissions']
];
$xx = Apikey::create($dd);
return response()->json(['status' => 'ok', 'apikey_id' => $xx->id]);
}
}
I want to test this code. I created two model factories like this.
$factory->define(Organization::class, function ($faker) use ($factory) {
return [
'name' => $faker->name,
'contact_name' => $faker->name,
'contact_phone' => '324567',
'contact_email' => $faker->email,
'address1' => 'xxx',
'state' => 'Newyork',
'city' => 'Newyork',
'country' => 'USA'
];
});
$factory->define(Apikey::class, function ($faker) use ($factory) {
return [
'key' => 'xxx',
'secret' => 'xxxx',
'permissions' =>'111',
'organization_id' => 7
});
My testing function looks like this.
public function testApiKeyGeneration ()
{
factory(App\Organization::class)->create()->each(function($u) {
$data = [
'organization_id' => $u->id,
'permissions' => '111'
];
$this->post('/createapikeyfororg' , $data)
->seeJson(['status' => 'ok']);
});
}
The controller works perfectly. It is only in the testing I am having problems. The url '/createapikeyfororg' is the url that invokes the controller method generateApiKeyGivenOrganizationId(). Is this testing procedure correct? I am yet to try it out and I am asking this question on a Saturday because I am really in a hurry. I am a total novice at testing and I am in a hurry and any help would be appreciated.

Request Data to Model Function

I'm trying to find out why when I dd($request->all()) in the store method of my controller everything is correct, however when I send it to the model function register() its no where to be seen.
I'm not quite sure what I'm doing wrong.
<?php
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class UsersController extends Controller
{
public function store(Request $request, User $user)
{
$this->authorize('delete', $user);
$this->validate($request, [
'firstName' => 'required|min:3',
'lastName' => 'required|min:3',
'displayName' => 'required|min:3',
'emailAddress' => 'required|email|unique:users,email',
'password' => 'required|min:3',
'role' => 'required|exists:roles,id'
]);
$userRegistered = $user->register(
new User($request->all())
);
if ($userRegistered) {
flash()->success('Success', 'The user has been successfully created!');
} else {
flash()->error('Error', 'The user could not be successfully created!');
}
return redirect()->to(route('users'));
}
}
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Authenticatable
{
use SoftDeletes;
/**
* Fillable fields for a user.
*
* #var array
*/
protected $fillable = [
'first_name',
'last_name',
'display_name',
'email',
'password',
'role_id'
];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function register(User $user)
{
return $user->create([
'first_name' => $user->firstName,
'last_name' => $user->lastName,
'display_name' => $user->displayName,
'email' => $user->emailAdress,
'password' => $user->password,
'role_id' => $user->role
]);
}
}
You've mixed up the formatting of your variables between your request data and your User model.
According to your validation logic, the request data is coming is as camelCase. Yet, according to your $fillable array, the fields on your User model are snake_case. But, even then, in your register method, you're attempting to access the fields on the User model using camelCase.
You haven't given enough information for a definitive answer, but you need to fix the formatting of your variables. For example, change your request fields names from camelCase to snake_case, and make sure you access your fields on the model using snake_case.
You have to pass a list of attributes to "validate" method.
//...
$this->validate($request->all(), [
'firstName' => 'required|min:3',
'lastName' => 'required|min:3',
'displayName' => 'required|min:3',
'emailAddress' => 'required|email|unique:users,email',
'password' => 'required|min:3',
'role' => 'required|exists:roles,id'
]);
One more thing..check if you are using "web" middleware. (Kernel.php => MiddlewareGroups). Add that middleware to your route.

Resources