Laravel Passport clients has user_id null - laravel

I am making a react app that uses a laravel passport backend to get and post data from a database. I have full control over the app code and the laravel backend code.
I can make an access token just fine, either using a client, or simply by issuing a user to make one, but I can't use this access token to access data, as described here. Sending such a request with the generated access token gives me a 401 every time.
I believe My problem is when making clients. I have 2 clients (made when running php artisan passport:install), but they both have user_id=null. I'm assuming this should be set some integer when a user uses the client to for example issue an access token? But, it doesn't.
So, does anyone have any idea of what I am doing wrong?
Below I am posting my user model, and the migration files users and oath_clients. Feel free to ask for more code if needed!
User model:
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'api_token', 'redcap_token', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
Users 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('api_token', 60)->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
Oauth migrations
class CreateOauthClientsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('oauth_clients', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->index()->nullable();
$table->string('name');
$table->string('secret', 100);
$table->text('redirect');
$table->boolean('personal_access_client');
$table->boolean('password_client');
$table->boolean('revoked');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('oauth_clients');
}
}

Sounds like to me you need to reference the relationship that a User hasOne OAuth and a OAuth belongsTo a User. Add this to your oauth_clients migration:
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('user');
https://laravel.com/docs/5.7/migrations#foreign-key-constraints
Then include the necessary relationships in the Models. Hope this helps!
// User's Table
public function oauth()
{
return $this->hasOne(OAuth::class, 'user_id');
}
// OAuth Table
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}

It is the Qauth migration where the user_id can be null
$table->integer('user_id')->index()->nullable();
either you pass this when you add the clients using for example uuid or set this as increment..

Related

Laravel - 1215 Cannot add foreign constraint

I am trying to link up to three tables together but when I run my migration (using artisan) I keep getting an error:
General error: 1215 Cannot add foreign key constraint (SQL: alter table stores add constraint stores_sale_id_foreign foreign key (sale_id) references bikes (id))
Here is my migration file for stores:
class CreateStoresTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('stores', function (Blueprint $table) {
$table->increments('id');
$table->string('store_name');
$table->string('city');
$table->string('manager');
$table->integer('sale_id')->unsigned();
$table->timestamps();
});
Schema::table('stores', function ($table){
$table->foreign('sale_id')->references('id')->on('bikes');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down() {
Schema::dropIfExists('stores');
}
}
store model:
class Store extends Model {
use HasFactory;
protected $table = 'stores';
protected $fillable = ['store_name', 'city', 'manager', 'sale_id'];
}
Edit:
bikes migration:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateBikesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('bikes', function (Blueprint $table) {
$table->increments('id');
$table->string('make');
$table->string('model');
$table->string('category');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('bikes');
}
}
Instead of increments try $table->id()or $table->bigIncrements('id') for both tables.
Because the id column will then have the right type.
You will also need to set your foreign key column to $table->unsignedBigInteger('sale_id'); to set the right column type fore the foreign constraint.
And you will have to make sure that your bikes migration runs before your stores migration.
try this,
class CreateStoresTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('stores', function (Blueprint $table) {
$table->increments('id');
$table->string('store_name');
$table->string('city');
$table->string('manager');
$table->integer('sale_id')->unsigned()->nullable();
$table->timestamps();
$table->foreign('sale_id')->references('id')->on('bikes')->onDelete('cascade')->onUpdate('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down() {
Schema::dropIfExists('stores');
}
}
Use this code
class CreateStoresTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('stores', function (Blueprint $table) {
$table->increments('id');
$table->string('store_name');
$table->string('city');
$table->string('manager');
$table->unsignedInteger('sale_id')->nullable();
$table->foreign('sale_id')->references('id')->on('bikes')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down() {
Schema::dropIfExists('stores');
}
}
Note: Make sure there should not be a mismatch in foreign key field types.
Either change original migration from increments() to just
bigIncrements()
Or in your foreign key column do unsignedBigInteger() instead of unsignedInteger().

How do I create A joined table in Laravel Migration?

I have a users table with the following columns with User model has one to many relationship with phone model.
create_users_table.php
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
Then I have a phones table, which has a foreign key of user_id
create_phones_table.php
public function up()
{
Schema::create('phones', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('user_id')->unsigned();
$table->string('phone');
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
});
}
My User Model
<?php
namespace App;
use App\Phone;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* Define Relationship
*/
public function phones()
{
return $this->hasMany(Phone::class);
}
}
My Phone Model
<?php
namespace App;
use App\User;
use Illuminate\Database\Eloquent\Model;
class Phone extends Model
{
protected $table = 'phones';
protected $fillable = ['phone' , 'user_id'];
public function user()
{
return $this->belongsTo(User::class);
}
}
I would like to have a third table in my database call phone_user_table.php. Something like a pivot table where I have joined the user table and phone table where I can see all the records. This is my code where I attempt to join the table.
create_phone_user.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePhoneUser extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('phone_user', function (Blueprint $table) {
$table->unsignedBigInteger('user_id')->unsigned();
$table->unsignedBigInteger('phone_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('phone_id')->references('id')->on('phones')->onDelete('cascade');
$table->timestamps();
$table
->join('users', 'users.id', '=', 'phone_user.user_id')
->join('phones', 'phones.id', '=', 'phone_user.phone_id')
->select('phone_user.*', 'users.name', 'phones.phone')
->get();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('phone_user');
}
}
However, it seems to be giving Base Table phones already exist.
Appreciate all the help given.
Thank you.
This is how it works base on Laravel Many to Many Relationship Docs.
First
You need to create 2 model that you would like to have relationship.
In your example you have USER and PHONE relationship.
In your User Model you need to declare the relationship like this:
public function phones() {
return $this->belongsToMany(Phone::Class);
}
And In your Phone Model you can do like this:
public function users() {
return $this->belongsToMany(User::Class);
}
SECOND
You need to have 3 migration one is for the user, phone and also the phone_user. So it should be look like this.
Phone User Migration
Schema::create('phone_user', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('phone_id')->index();
$table->unsignedBigInteger('user_id')->index();
$table->timestamps();
$table->foreign('phone_id')->references('id')->on('phones')->onDelete('cascade');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
Note: You don't need to have the unsignedBigInteger in both user and phone migration.
When you have a user list and a phone list you can now assign the phone to the user like this:
Controller
$user = User::find(1);
$phone = Phone::find(1);
$user->phones()->attach($phone);

How to get the login log in Laravel 5.2

I am using Laravel 5.2, I would want to record user's login log, including user id,ip address and timestamps. what should I do?
//migration code
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class LoginHistory extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('login_history', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->string('ip')->default(false);
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('login_history');
}
}
I am using Laravel 5.2, I would want to record user's login log, including user id,ip address and timestamps. what should I do?

eager load comments with posts in laravel, how to setup the DB and Models?

So, I checked a tutorial for a simple blog that had function to post comments on a post.
I had my post migration already and I wanted to add comments to post.
The posts have a picture of an item and a description.
So my migration is:
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('posts' ,function(Blueprint $table){
$table->increments('id')->unsigned()->unique();
$table->unsignedInteger('user_id')->unsigned();
$table->unsignedInteger('item_id')->unsigned();
$table->string('picture', 255)->nullable();
$table->text('description')->nullable();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
$table->foreign('item_id')
->references('id')
->on('items')
->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('posts');
}
}
so I have a table with the post id, the user_id of the poster, the item_id of the item whose picture is being posted, the picture and a description.
Now I thought, ok I have to add comments to these posts so I need a comments table and I made one like this:
class CreateCommentsTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('comments', function(Blueprint $table)
{
$table->increments('id');
$table -> integer('post_id')->unsigned()->default(0);
$table->foreign('post_id')
->references('id')->on('posts')
->onDelete('cascade');
$table -> integer('user_id')->unsigned()->default(0);
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
$table->text('body');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
// drop comment
Schema::drop('comments');
}
}
where I have the id of the comments, the post_id of the post the comment refers to and, the user_id of the commenter and the comment body.
This should be a one to many relationship problem right? A post can have many comments.
So the models are:
class Comment extends Model
{
/**
*
* The comment belongs to one author
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function author()
{
return $this->belongsTo('App\User');
}
/**
*
* The comment belongs to one post
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function post()
{
return $this->belongsTo('App\Post');
}
}
...
class Post extends Model
{
/**
*
* a post has many comments
*
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function comments()
{
return $this->hasMany('App\Comments');
}
/**
*
* a post belongs to one author
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function author()
{
return $this->belongsTo('App\User');
}
}
...
class User extends Model
{
//..... (some more stuff here not related to comments.
public function comments()
{
return $this->hasMany('App\Comment');
}
}
Now the point is, if I want to return all users posts WITH comments and comments author, how should I modify the models?
you could do something like
$posts_with_comments = Post::with('author', 'comments')->get();
you can add as many relations as you want to load with it, check out the eager docs
https://laravel.com/docs/4.2/eloquent#eager-loading
try this
$user = Auth::user(); $posts = Post::with('comments', 'author')->where('user_id', $user->id )->get();
you are using the user object not the user id in the 'where'

Laravel 5.1 how to attach the Order to a User using Pivot Tables?

So i am trying to build a structure where One User can have Many Orders and One order has 2 Users(eg: the customer and the employee servicing that order).
This is my migrations:
Orders to Users:
Schema::create('order_user', function (Blueprint $table) {
$table->increments('id')->unsigned();
$table->integer('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->integer('order_id')->unsigned()->index();
$table->foreign('order_id')->references('id')->on('orders')->onDelete('cascade');
$table->timestamps();
});
Order:
Schema::create('orders', function (Blueprint $table) {
$table->increments('id');
$table->string('boostFrom')->nullable();
$table->string('boostTo')->nullable();
$table->string('numGames')->nullable();
$table->decimal('totalPrice');
$table->string('ipnStatus');
$table->timestamps();
});
Users:
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('email')->unique();
$table->string('password', 60);
$table->rememberToken();
$table->timestamps();
});
I have not set relationships yet since i test with them already in my User and Order Models. But when i try to attach the Order to User using:
$user->order()->attach(4);
I get an error relating to Builder.php saying attach() does not exist, but i was following the laravel 5.1 docs to try to attach the order.
Could you please let me know how i should structure everything so when an order is created then i can attach that to a user.
Thanks
As Requested:
class Order extends Model
{
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'orders';
public function users()
{
return $this->hasMany('App\Models\User');
}
}
class User extends Model implements AuthenticatableContract, CanResetPasswordContract, HasRoleAndPermissionContract
{
use Authenticatable, CanResetPassword, HasRoleAndPermission;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = ['name', 'email', 'password'];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = ['password', 'remember_token'];
protected $guarded = ['id'];
public function orders()
{
return $this->hasMany('App\Models\Order');
}
}
Error in Tinker:
>>> $user->orders()->attach(4)
BadMethodCallException with message 'Call to undefined method Illuminate\Database\Query\Builder::attach()'
You should be using belongsToMany, instead of hasMany, since you have a many-to-many relationship. The hasMany is used to define a one-to-many relation. So you should have this:
// Order.php
public function users()
{
return $this->belongsToMany('App\Models\User');
}
and this
// User.php
public function orders()
{
return $this->belongsToMany('App\Models\Order');
}

Resources