Problem
We wanted to implement Loopback.io as an API for our mobile app development, but needed it to play nice with our Yii2 web environment. We needed to be able to authenticate our Loopback / API users on the same user table that we authenticate our website users, using the same encrypted password.
Solution
This ended up being easier than I thought. Here are the steps that I followed:
- Create an AppUser class that inherits from User.
- Override the table that the AppUser class uses as its datastore.
- Create some Loopback fields in my user table.
- Tell AppUser to use the pre-existing primary key
- Turn off email validation
1. Create an AppUser Class to inherit from User
I took my cues from the documentation on how to make a class that extends User. Download the example referenced in the documentation to get the files. However, I called my class "AppUser" instead of "user", changing user.js and user.json to app-user.js and app-user.json.
I list my AppUser.json below. I left the AppUser.js as it was provided.
2. Override the table the ash AppUser class uses as its datastore.
By default, Loopback will try to use a table called AppUser to match the name of the class. In my example, I need it to reference the user table in the database, which my Yii2 application already uses. I used the documentation on this page. to figure out how to do this.
In the AppUser.json file, add the following section:
"options": {
"mysql": {
"table": "user"
}
},
Where user is the name of my table that I want the AppUser class to use as its datastore, instead of the default "AppUser" table.
3. Create some Loopback fields in my user table.
I added these columns, but perhaps I could have excluded them according to the documentation on this page.
ALTER TABLE `user` ADD `realm` varchar(512);
ALTER TABLE `user` ADD `emailVerified` tinyint(1);
ALTER TABLE `user` ADD `verificationToken` varchar(512);
4. Tell AppUser to use the pre-existing primary key
I already had my own user_id column setup as the primary key. Loopback will try to use a column called id as the primary key by default. To prevent that, I set the field in the properties section with "id": "true" so that AppUser knows to use user_id as the primary key.
"properties": {
"user_id": {
"type": "number",
"id": true
},
"account_id": {
"type": "number",
"required": "true"
}
}
(I setup the account_id field as my Loopback app will need to reference that column. You would setup your other column/fields under properties)
I also set the idInjection section to false, so Loopback won't try and use the "id" field.
"idInjection": false,
5. Turn off email validation.
Insert the following in the AppUser.js file. "emailVerificationRequired": false,
Here is my entire AppUser.json file:
{
"name": "AppUser",
"base": "User",
"idInjection": false,
"restrictResetPasswordTokenScope": true,
"emailVerificationRequired": false,
"validations": [],
"relations": {},
"acls": [
{
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "DENY"
},
{
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW",
"property": "login"
},
{
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW",
"property": "logout"
},
{
"principalType": "ROLE",
"principalId": "$owner",
"permission": "ALLOW",
"property": "findById"
},
{
"principalType": "ROLE",
"principalId": "$owner",
"permission": "ALLOW",
"property": "updateAttributes"
}
],
"methods": {},
"options": {
"mysql": {
"table": "user"
}
},
"properties": {
"user_id": {
"type": "number",
"id": true
},
"account_id": {
"type": "number",
"required": "true"
}
}
}
Hi Jack Torrance,
ReplyDeleteThank you for the nice article. It really helped me.
Can you also please let me know is there a way to use the existing user table's email and password for loopback login?
Note the existing password has md5 and I do not want to change anything over the existing DB.
Please let me know if you need more details.
Thank you,
Vivek
Hi Vivek, yes, as long as your user table has a field named 'email', Loopback will use that field to authenticate people with their email address.
DeleteSomehow I'm not getting it right. I have email, username, password in user table. But every time when I try to access /user/login/ it gives me login failed.
ReplyDeleteI will try one more time let me check.
If you have any working sample/example please share with me.
Thank you,