Skip to content

Authentication

Jonathan Casarrubias edited this page Sep 11, 2017 · 1 revision

FireLoop.io

Basic Authentication

The basic authentication, is the one provided by LoopBack but works for both interfaces the LoopBack's REST API and for the FireLoop Real-Time API.

LoopBack's default authentication is provided within any User based model, therefore when you generate an SDK you will need to use your user based services.

import { Component } from '@angular/core';
import { User, AccessToken, UserApi } from '../shared/sdk';

@Component({
  selector: 'app-login',
  template: `
  <h1>Login</h1>
  <form (submit)="login()">
    <input type="text" name="email" [(ngModel)]="user.email"/>
    <input type="password" name="password" [(ngModel)]="user.password"/>
    <button>Enter</button>
  </form>
`
})
export class LoginComponent {
  
  private user: User = new User();

  constructor(private userApi: UserApi) {}

  login(): void {
    this.userApi.login(this.user).subscribe(
      (token: AccessToken) => console.log(token),
      (err) => console.log(err)
    );
  }
}

In this example, after the login() method is executed and the authentication is successful, though you receive a valid token, you don't really need to follow other steps other than redirecting the user to an authenticated section.

This is because internally and by default the SDK will locally store a reference for that token, meaning that on every API request or when connecting through websockets, the SDK already knows the reference and will use it when needed.

Enable Auth for Real-Time

For an authenticated websocket connection, you still require to enable that configuration within the API component-config.json file

{
  "loopback-component-explorer": {
    "mountPath": "/explorer"
  },
  "@mean-expert/loopback-component-realtime": {
    "debug": false,
    "auth": true // Enable Auth
  }
}

When Auth is enabled, you must not create a real-time connection within the Login section.

After you redirect from login to another section and due the nature of component oriented programming, within each component you need to verify either if FireLoop is connected (ready) or already authenticated

import { Component, OnInit } from '@angular/core';
import { RealTime, FireLoopRef, Todo } from './shared/sdk';
import { Subscription } from 'rxjs/Subscription';

@Component({
  selector: 'app-todo',
  templateUrl: './todo.component.html',
  styleUrls: ['./todo.component.css']
})

export class TodoComponent implements OnInit {
   
  private todoRef: FireLoopRef<Todo> = new Todo();
  private todoSub: Subscription;

  constructor(private realTime: RealTime) { }

  ngOnInit() {
    if (
      this.realTime.connection.isConnected() &&
      this.realTime.connection.authenticated
    ) {
      this.realTime.onReady().subscribe(() => this.setup());
    } else {
      this.realTime.onAuthenticated().subscribe(() => this.setup());
      this.realTime.onReady().subscribe();
    }
  }
  
  setup(): void {
    // Make sure you never have duplicated references and subscriptions
    this.ngOnDestroy();
    this.todoRef = this.realTime.FireLoop.ref<Todo>();
    this.todoSub = this.todoRef.on('change').subscribe((todos: Todo[]) => console.log(todos));
  }

  ngOnDestroy() {
    if (this.todoRef) this.todoRef.dispose();
    if (this.todoSub) this.todoSub.unsubscribe();
  }
}

By this moment you should be receiving todos from an authenticated connection, but you still need to secure your methods by using ACLs

{
  "acls": [
    {
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "$everyone",
      "permission": "DENY"
    },
    {
      "accessType": "READ",
      "principalType": "ROLE",
      "principalId": "$authenticated",
      "permission": "ALLOW"
    }
  ]
}

If you want to know more about ACLs please verify the following ACL Documentation

Clone this wiki locally