Skoči do sadržaja

Tomislav Stanković

Sam svoj bloger

  • TomislavStankovic.Com
  • Blog
  • Brisalica.Com
  • Krntija.Com

Kategorije

  • Digitalno (14)
  • Događanja (17)
  • Financije (8)
  • Izleti i putovanja (13)
  • Knjige (14)
  • Online reputacija (59)
  • Poslovna komunikacija (10)
  • Razno (34)
  • Razvoj (135)
    • Backend (13)
    • Frontend (24)
    • Mobile (90)
  • Startup (4)

Komentari

  • Postupak kupovine državnih obveznica Republike Hrvatske putem platforme E-RIZNICA - Tomislav Stanković o Interactive Brokers – postupak otvaranja brokerskog računa
  • Kako deaktivirati ili izbrisati Postcrossing profil? - Brisalica.Com o Postcrossing: kada ste posljednji put poslali razglednicu?
  • Goran Galinec o Prikaz podataka API-ja Sudskog registra – pravosudje.hr
  • Tomislav Stanković o Prikaz podataka API-ja Sudskog registra – pravosudje.hr
  • Goran Galinec o Prikaz podataka API-ja Sudskog registra – pravosudje.hr
profile for Tomislav Stankovic at Stack Overflow, Q&A for professional and enthusiast programmers

DISKLEJMER

Stavovi i mišljenja na ovom blogu moji su osobni stavovi i ne odražavaju stavove mojih poslovnih partnera i tvrtki u kojima radim ili s kojima surađujem.

Uvjeti korištenja

Oznaka: login

Ionic & Facebook login/prijava – Invalid key hash

Ionic & Facebook login/prijava – Invalid key hash

U blog postu pod naslovom “Ionic 3 – Facebook prijava” pokazao sam kako omogućiti Facebook login/prijavu unutar Ionic aplikacije.

Primjer iz tog blog posta uredno radi u razvojnoj verziji mobilne aplikacije tj. prilikom testiranja, ali kada se aplikacija jednom stavi u produkciju tj. na Google Play Store može se dogoditi da login/prijava više ne radi bez nekog očitog razloga i jedina greška koju je moguće vidjeti je:

Invalid key hash. The key hash **************************** does not match any stored key hashes. Configure your app key hashes at https://developers.facebook.com/apps/appid

Ionic & Facebook login/prijava – Invalid key hash

facebook for developers

Rješenje je u biti vrlo jednostavno što se zaključiti prema zadnjoj rečenici poruke o grešci. Potrebno je otići na https://developers.facebook.com/ tj. na adresu profila aplikacije https://developers.facebook.com/apps/appid/ te pod Settings – Basic – Android – Key Hashes kopirati hash key iz poruke o grešci.

Ionic & Facebook login/prijava - Invalid key hash

Nakon ovoga će login/prijava ponovno raditi bez ikakvih problema.

Objavljeno dana 20/05/201919/05/2019Kategorije Mobile, RazvojOznake facebook, Ionic Framework, login, prijava1 komentar na Ionic & Facebook login/prijava – Invalid key hash
Ionic & Google Firebase login/prijava – Error Code 10

Ionic & Google Firebase login/prijava – Error Code 10

U blog postu pod naslovom “Ionic 3 – Google login/prijava” pokazao sam kako omogućiti Google login/prijavu unutar Ionic aplikacije.

Primjer iz tog blog posta uredno radi u razvojnoj verziji mobilne aplikacije tj. prilikom testiranja, ali kada se aplikacija jednom stavi na Google Play Store može se dogoditi da login/prijava više ne radi bez nekog očitog razloga i jedina greška koju je moguće vidjeti je “10”.

Google Play Store – Error Code 10

Kako bi se ova greška riješila potrebno je napraviti sljedeće:

1.) Na adresi https://play.google.com/apps/publish/ pronaći aplikaciju u kojoj prijava ne radi, omogućiti “App Signing by Google Play” i onda u izborniku s lijeve strane kliknuti na Release management – App signing te kopirati SHA-1 certificate fingerprint.

App Signing by Google Play

2.) Na adresi https://console.firebase.google.com/project/naziv-projekta/ otići na Project settings – SHA certificate fingerprints i kliknuti na Add fingerprint te ovdje zalijepiti ranije kopiran SHA-1 ključ.

Google Firebase Console

Nakon ovoga login/prijava će ponovno raditi bez ikakvih problema.

Objavljeno dana 15/04/201914/04/2019Kategorije Mobile, RazvojOznake Error Code 10, Firebase, Google Plus, Ionic, login, prijavaOstavite komentar na Ionic & Google Firebase login/prijava – Error Code 10
SMS login – Angular & Firebase

SMS login – Angular & Firebase

U nastavku ovog blog posta pokazati ću kako napraviti jednostavnu Angular web aplikaciju sa funkcionalnom SMS prijavom.

Prednosti korištenja SMS prijave:

– Sprečavanje lažnih korisnika – korištenjem SMS prijave onemogućava se kreiranje lažnih korisnika jer svaki korisnik koji se želi prijaviti treba imati jedinstveni broj telefona na koji će dobiti kod pomoću kojega će se prijaviti.
– Daje dodatnu vrijednost bazi korisnika – svaki potvrđeni korisnik koji stoji iza svakog od tih brojeva telefona predstavlja određenu vrijednost jer možemo biti sigurni da to nije lažni korisnik.
– Povećana sigurnost i poboljšava korisničko iskustvo – u današnje vrijeme korisnici koriste jako puno raznih aplikacija i postaje sve teže pratiti login podatke svake od njih. Omogućavanjem SMS prijave korisnik ne mora smišljati novo korisničko ime ili lozinku nego je samo dovoljno da uz sebe ima svoj mobitel kako bi se uspješno prijavio. Također, treća strana se ne može prijaviti kao npr. ja ako uz sebe nema moj mobilni telefon da pročita kod čime se drastično povećava sigurnost.

Kreiranje projekta

Kreiram novi Angular web projekt koristeći Angular CLI.

Shell
1
2
$ ng new angular-firebase-sms-login
$ cd angular-firebase-sms-login

Angular CLI start screen

Google Firebase

Nakon što sam kreirao Angular projekt mogu se prebaciti na Google Firebase i ondje postaviti projekt kako bi uopće mogao koristiti SMS login.

Google Firebase Console

Kroz nekoliko sekundi Firebase projekt će biti spreman.

Google Firebase Console

Unutar izbornika Develop – Authentication potrebno je odabrati Sign-in-method tab. Ondje se nalazi popis opcija dostupnih za login/prijavu.

Google Firebase Console

Ja ću, naravno, ovaj put odabrati Phone.

Allow users to sign in with a mobile phone number, using Firebase SDK phone verification and user authentication tools.

Google Firebase Console Phone

Phone tj. SMS prijava je aktivirana.

Google Firebase Console Phone

Ako sada u izborniku Authentication – Users pogledam popis korisnika on će biti prazan jer za sada još nisam napravio niti jednu prijavu. Nakon što se sa bilo kojim brojem mobitela prvi put prijavim taj će se broj prikazati kao novi korisnik.

Firebase users

Prema trenutnim postavkama moj će projekt raditi ako web aplikaciju pokrenem na adresi http://localhost:4200/.

Firebase Authorized domains

Međutim ako imam neku (pod)domenu kao npr. test.angularaplikacija.com ondje prijava putem SMS-a neće raditi dok ručno ne odobrim tu (pod)domenu.

To use Firebase Authentication in a web app, you must whitelist the domains that the Firebase Authentication servers can redirect to after signing in a user.

By default, localhost and your Firebase project’s hosting domain are whitelisted. You must whitelist the full domain names of any other of your web app’s hosts. Note: whitelisting a domain allows for requests from any URL and port of that domain.

Firebase Authorized domains

Prije nego se vratim svojem Angular projektu trebaju mi još neki podaci bez kojih moj Angular projekt ne bi znao kako se povezati s Firebaseom.

Ovdje idem na Project settings.

Google Firebase Settings

Nakon toga idem na Add Firebase to your web app.

Google Firebase Settings

I konačno, ovdje imam konfiguracijski config objekt koju ću kasnije postaviti u svoj Angular projekt i tako ga povezati sa Firebaseom.

Google Firebase Settings

Implementacija prijave/logina

Sada se vraćam u svoj Angular projekt.

AppComponent ću malo prilagoditi tj. dodati joj nekoliko detalja kojih trenutno nema.

app.component.ts
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { Component,
         OnInit,
         Injectable } from '@angular/core';
 
@Injectable()
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
 
export class AppComponent implements OnInit {
 
  title = 'angular-firebase-sms-login';
 
  constructor() {
  }
 
  ngOnInit() {
  }
 
}

Trebat će mi window objekt pa ću napraviti servis za njega kako bi ga mogao pozivati u cijelog projektu sa jednog mjesta.

Shell
1
$ ng g service window

U servisu se nalazi sljedeće:

window.service.ts
JavaScript
1
2
3
4
5
6
7
8
9
10
import { Injectable } from '@angular/core';
 
@Injectable()
export class WindowService {
 
  get windowRef() {
    return window
  }
 
}

Sada sam spreman za dodavanje Firebasea unutar projekta, a to radim naredbama:

Shell
1
2
$ npm install --save firebase
$ npm install angularfire2 firebase --save

Sada sve to trebam navesti unutar app.module.ts datoteke. Ovdje moram uvesti FormsModule zato što ću u login formi koristiti [(ngModel)].

app.module.ts
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
 
import { AppComponent } from './app.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { FormsModule } from '@angular/forms';
 
import { AngularFireModule } from 'angularfire2';
import { AngularFireAuthModule } from 'angularfire2/auth';
 
export const firebaseConfig = {
  apiKey: "***************************************",
  authDomain: "angular-firebase-sms-login.firebaseapp.com",
  databaseURL: "https://angular-firebase-sms-login.firebaseio.com",
  projectId: "angular-firebase-sms-login",
  storageBucket: "angular-firebase-sms-login.appspot.com",
  messagingSenderId: "************"
};
 
@NgModule({
  declarations: [
    AppComponent,
    DashboardComponent
  ],
  imports: [
    BrowserModule,
    AngularFireModule.initializeApp(firebaseConfig),
    AngularFireAuthModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Na ekranu će to izgledati ovako:

app.component.html
XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<div style="text-align:center">
  <h1>
    Welcome to {{ title }}!
  </h1>
  <img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
  
  <div [hidden]="user" style="text-align:center">
    <label for="phone">Broj mobitela:</label><br>
    <input type="text" [(ngModel)]="phoneNumber.country" class="input" placeholder="+385"  maxlength="4">
    <input type="text" [(ngModel)]="phoneNumber.line"  class="input" placeholder="9********" maxlength="9">
  
    <div id="recaptcha-container"></div>
  
    <button (click)="sendLoginCode()">Pošalji SMS</button>
  
    <div *ngIf="windowRef.confirmationResult">
      <hr>
      <label for="code">Ovdje unesite svoj pin</label><br>
      <input type="text" name="code" [(ngModel)]="verificationCode">
  
      <button (click)="verifyLoginCode()">Potvrdi</button>
    </div>
  </div>
 
  <div *ngIf="user">
    <p>Prijava uspješna!</p>
    <p>UserId: {{ user?.uid }}</p>
  </div>
 
</div>

Funkcionalnost se može vidjeti u nastavku, a sastoji se od nekoliko funkcija. Osnova svega je broj mobitela koji je u E.164 obliku.

app.component.ts
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import { Component, OnInit, Injectable } from '@angular/core';
import { WindowService } from './window.service';
 
import { AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase/app';
 
export class PhoneNumber {
  country: string = "+385";
  line: string;
  get e164() {
    const num = this.country + this.line
    return `+${num}`
  }
}
 
@Injectable()
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [WindowService]
})
export class AppComponent implements OnInit {
  
  title = 'Angular Firebase SMS Login';
 
  windowRef: any;
  phoneNumber = new PhoneNumber()
  verificationCode: string;
  user: any;
 
  constructor(
    private win: WindowService,
    public _angularAuth: AngularFireAuth) {
  }
 
  ngOnInit() {
    this.windowRef = this.win.windowRef;
    this.windowRef.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container')
    this.windowRef.recaptchaVerifier.render();
  }
 
  sendLoginCode() {
    const appVerifier = this.windowRef.recaptchaVerifier;
    const num = this.phoneNumber.e164;
    firebase.auth().signInWithPhoneNumber(num, appVerifier)
            .then(result => {
                this.windowRef.confirmationResult = result;
            })
            .catch( error => console.log(error) );
  }
 
  verifyLoginCode() {
    this.windowRef.confirmationResult
                  .confirm(this.verificationCode)
                  .then( result => {
                    this.user = result.user;
                    console.log(this.user);
    })
    .catch( error => console.log(error, "Pogrešan kod?"));
  }
 
}

U praksi to izgleda ovako:

SMS login – Angular & Firebase

Klikom na “Pošalji SMS” šalje se SMS poruka na uneseni broj mobitela.

Firebase SMS

Nakon unosa koda iz SMS-a uspješno se prijavljujem.

Angular & Firebase

U slučaju da se idem nekoliko puta za redom prijaviti i Google Firebase posumnja na zloupotrebu pojavit će se napredna reCAPTCHA.

Firebase Phone Authentication With Angular 4 Tutorial
Izvor: https://angularfirebase.com/lessons/firebase-phone-authentication-with-angular-4-tutorial/

Tek sada, nakon što je prijava uspješno prošla, mogu svoj broj mobitela vidjeti unutar Google Firebase sučelja.

Firebase users

Zaključak

Ovo je bio primjer jednostavne Angular web aplikacije sa SMS prijavom gdje se sva logika odvija na klijentskoj strani. Nedavno sam napravio i verziju gdje se sva logika odvija na serverskoj strani unutar NodeJS-a sa dodatnim sigurnosnim provjerama. Bilo bi previše za ovaj blog post da sam išao i taj dio obraditi. Možda u nekom od sljedećih blog postova, ako netko od posjetitelja bloga bude zainteresiran.

Osim SMS prijave obradio sam nekoliko tema s ostalim vrstama prijave kao što su:
– Angular & Firebase – registracija i prijava
– Ionic 3 – Google login/prijava
– Ionic 3 – Facebook prijava
– Ionic 3 – Firebase registracija i prijava

Struktura projekta prema package.json

package.json
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
{
  "name": "angular-firebase-sms-login",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "~7.1.0",
    "@angular/common": "~7.1.0",
    "@angular/compiler": "~7.1.0",
    "@angular/core": "~7.1.0",
    "@angular/forms": "~7.1.0",
    "@angular/platform-browser": "~7.1.0",
    "@angular/platform-browser-dynamic": "~7.1.0",
    "@angular/router": "~7.1.0",
    "angularfire2": "^5.1.1",
    "core-js": "^2.5.4",
    "firebase": "^5.7.2",
    "rxjs": "~6.3.3",
    "tslib": "^1.9.0",
    "zone.js": "~0.8.26"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.11.0",
    "@angular/cli": "~7.1.4",
    "@angular/compiler-cli": "~7.1.0",
    "@angular/language-service": "~7.1.0",
    "@types/node": "~8.9.4",
    "@types/jasmine": "~2.8.8",
    "@types/jasminewd2": "~2.0.3",
    "codelyzer": "~4.5.0",
    "jasmine-core": "~2.99.1",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~3.1.1",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "~2.0.1",
    "karma-jasmine": "~1.1.2",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.4.0",
    "ts-node": "~7.0.0",
    "tslint": "~5.11.0",
    "typescript": "~3.1.6"
  }
}

Objavljeno dana 07/01/201906/01/2019Kategorije Frontend, RazvojOznake Angular, Google Firebase, login, SMSOstavite komentar na SMS login – Angular & Firebase
Angular & Firebase – registracija i prijava

Angular & Firebase – registracija i prijava

U ovom ću blog postu napraviti primjer Angular web aplikacije koja će se sastojati od nekoliko ekrana. Glavna svrha ove web aplikacije je omogućiti korisnicima da se registriraju tj. prijave kako bi ju mogli koristiti. To će moći učiniti koristeći e-mail, Google ili Facebook korisnički račun.

Nekoliko sam blog postova već objavio na ovu temu, ali svi su bili vezani uz Ionic Framework. Iako je Ionic temeljen na Angularu shvaćam da osobama koje se tek susreću sa ovim može biti teže napraviti Angular projekt proučavajući Ionic sintaksu. Zato ovaj put radim čisti Angular web projekt.

Postavljanje Firebase projekta

Na adresi https://console.firebase.google.com/ kreiram novi Firebase projekt pod nazivom ‘AngularWebFirebase’.

Angular & Firebase – registracija i prijava

Na sljedećem ekranu, klikom na ‘Add Firebase to your web app‘ dobijem objekt koji će mi biti potreban kako bi sve funkcioniralo. Taj ću objekt kasnije ugraditi unutar app.module.ts datoteke.

Angular & Firebase – registracija i prijava

Nakon postavljanja projekta u izborniku Authentication odabirem Email/Password, Facebook i Google metodu registracije/prijave.

Angular & Firebase – registracija i prijava

Kao što se može vidjeti iz slike iznad, Facebook prijava ne može se ugraditi bez dva parametra koja je moguće dobiti jedino na adresi https://developers.facebook.com/ gdje je potrebno kreirati profil za AngularWebFirebase aplikaciju.

Implementacija Firebase u Angular

Koristeći Angular CLI kreiram novi projekt.

Shell
1
2
$ ng new AngularWebFirebase
$ cd AngularWebFirebase

Sljedećom naredbom instaliram potreban NPM paket

Shell
1
$ npm install angularfire2 firebase --save

Također, kao što sam ranije već spomenuo, u datoteku app.module.ts postavljam potreban Firebase objekt.

app.module.ts
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
 
import { AppComponent } from './app.component';
import { AngularFireModule } from 'angularfire2';
import { AngularFireAuthModule } from 'angularfire2/auth';
 
export const firebaseConfig = {
  apiKey: "***************************************",
  authDomain: "***********************.firebaseapp.com",
  databaseURL: "https://***********************.firebaseio.com",
  projectId: "***********************",
  storageBucket: "***********************.appspot.com",
  messagingSenderId: "************"
};
 
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    AngularFireModule.initializeApp(firebaseConfig),
    AngularFireAuthModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Sada ću kreirati četiri komponente od kojih će se sastojati moja Angular web aplikacija:

1 – LoginComponent – stranica za prijavu koristeći Facebook ili Google
2 – EmailComponent – stranica za prijavu koristeći e-mail
3 – SignupComponent – stranica za registraciju
4 – DashboardComponent – početna stranica nakon uspješne prijave

Shell
1
2
3
4
$ ng generate component login
$ ng generate component email
$ ng generate component signup
$ ng generate component dashboard

Ako sada pokrenem aplikaciju naredbom $ ng serve na adresi http://localhost:4200/ mogu vidjeti jedino standardnu Angular početnu stranicu.

Angular Demo CLI projekt localhost

S obzirom da ja u ovom slučaju želim vidjeti svoju Login komponentu kao početnu stranicu moram napraviti sljedeće. Unutar /src/app/ kreiram datoteku app.routes.ts sa sljedećim sadržajem:

app.routes.ts
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
 
import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { SignupComponent } from './signup/signup.component';
import { EmailComponent } from './email/email.component';
 
export const router: Routes = [
    { path: '', redirectTo: 'login', pathMatch: 'full' },
    { path: 'login', component: LoginComponent },
    { path: 'signup', component: SignupComponent },
    { path: 'email', component: EmailComponent },
    { path: 'dashboard', component: DashboardComponent}
]
 
export const routes: ModuleWithProviders = RouterModule.forRoot(router);

Naravno, tu još ide uvoz u app.module.ts

app.module.ts
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { AngularFireModule } from 'angularfire2';
import { AngularFireAuthModule } from 'angularfire2/auth';
import { LoginComponent } from './login/login.component';
import { EmailComponent } from './email/email.component';
import { SignupComponent } from './signup/signup.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { routes } from './app.routes';
...
declarations: [
    AppComponent,
    LoginComponent,
    EmailComponent,
    SignupComponent,
    DashboardComponent
  ],
imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    AngularFireModule.initializeApp(firebaseConfig),
    AngularFireAuthModule,
    routes
  ],
...

I nakon toga unutar datoteke app.component.html umjesto postojećeg sadržaja staviti <router-outlet></router-outlet>.

Login komponenta

Nalazi se na adresi http://localhost:4200/login i to je zadani pregled koji se pojavi prilikom prve posjete web aplikaciji.

Angular & Firebase – registracija i prijava

Ekran se sastoji od tri gumba. Facebook, Google i E-mail prijava uz mogućnost registracije.

login.component.html
XHTML
1
2
3
4
5
6
7
8
9
10
11
<div class="form-container">
  <img src="assets/images/login.png" id="login">
 
    <span class="error" *ngIf="error">{{ error }}</span>
 
  <button (click)="loginFb()" id="fb">Login with Facebook</button><br>
  <button (click)="loginGoogle()" id="google">Login with Google</button>
  <button routerLink="/email" id="email">Login with E-mail</button>
 
  <a routerLink="/signup" routerLinkActive="active" class="alc">Don't have an account?</a>
</div>

Gumb za prijavu putem Facebooka ili Googlea pozivaju funkciju dok klik ma gumb za prijavu putem e-maila otvara novu stranicu na kojoj se nalazi forma za unos e-maila i lozinke.

Ako prijava putem Facebooka ili Googlea prođe zapisujem podatke o korisniku (name, picture, email) u localStorage kako bi ih kasnije mogao prikazati na Dashboardu.

login.component.ts
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import { Component, OnInit } from '@angular/core';
 
import { AngularFireModule } from 'angularfire2';
import { AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase/app';
import { Router } from '@angular/router';
 
@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
 
  error: any;
 
  constructor(public _angularAuth: AngularFireAuth,
              private _router: Router) { }
 
  ngOnInit() {
  }
 
  loginGoogle(){
    let a = this;
    //this._angularAuth.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider());
    firebase.auth().signInWithPopup(new firebase.auth.GoogleAuthProvider())
    .then(function(authData) {
      console.log(authData);
      if(authData.credential.accessToken){
        localStorage.setItem('name', authData.additionalUserInfo.profile.name);
        localStorage.setItem('picture', authData.additionalUserInfo.profile.picture);
        localStorage.setItem('email', authData.additionalUserInfo.profile.email);
        a._router.navigate(['/dashboard']);
      }
    }).catch(function(error) {
      console.log(error);
      a.error = error.message;
    });
  }
 
  loginFb(){
    let a = this;
    //this._angularAuth.auth.signInWithPopup(new firebase.auth.FacebookAuthProvider());
    firebase.auth().signInWithPopup(new firebase.auth.FacebookAuthProvider())
    .then(function(authData) {
      console.log(authData);
      if(authData.credential.accessToken){
        localStorage.setItem('name', authData.additionalUserInfo.profile.name);
        localStorage.setItem('picture', authData.additionalUserInfo.profile.picture.data.url);
        localStorage.setItem('email', authData.additionalUserInfo.profile.email);
        a._router.navigate(['/dashboard']);
      }
    }).catch(function(error) {
      console.log(error);
      a.error = error.message;
    });
  }
 
}

Ovisno o postavkama unutar Firebasea jedan korisnik se (ne)može prijaviti koristeći istu e-mail adresu na različitim društvenim mrežama tj. ako se korisnik jednom prijavio koristeći Google, a kasnije se želi prijaviti koristeći Facebook dobiti će sljedeću poruku:

Angular & Firebase – registracija i prijava

Ta se opcija može promijeniti klikom na ‘One account per email address‘.

Angular & Firebase – registracija i prijava

Signup komponenta

Nalazi se na adresi http://localhost:4200/signup i osnovna svrha ovog ekrana je omogućiti korisnicima registraciju.

Angular & Firebase – registracija i prijava

Ekran se sastoji od dva polja za unos e-maila i lozinke.

signup.component.html
XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div class="form-container">
  <a routerLink="/login" id="goback">Go back</a>
 
  <h2>Registration</h2>
 
  <span class="error" *ngIf="error">{{ error }}</span>
    
  <form #formData='ngForm' (ngSubmit)="onSubmit(formData)">
 
    <input type="text" placeholder="E-mail" (ngModel)="email" name="email" class="txt" required>
    <input type="password" placeholder="Password" (ngModel)="password" name="password" class="txt" required>
 
 
    <button type="submit" [disabled]="!formData.valid" class="basic-btn">Create my account</button>
  </form>
</div>

Ako registracija prođe u redu korisnik automatski bude preusmjeren na stranicu za prijavu. U suprotnom iznad polja za unos e-maila prikazuje se poruka o grešci.

Angular & Firebase – registracija i prijava

signup.component.ts
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import { Component, OnInit } from '@angular/core';
 
import { AngularFireModule } from 'angularfire2';
import { AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase/app';
import { Router } from '@angular/router';
 
@Component({
  selector: 'app-signup',
  templateUrl: './signup.component.html',
  styleUrls: ['./signup.component.css']
})
export class SignupComponent implements OnInit {
 
  error: any;
 
  constructor(public _angularAuth: AngularFireAuth,
              private _router: Router) { }
 
  ngOnInit() {
  }
 
  onSubmit(formData) {
    let a = this;
    if(formData.valid) {
      console.log(formData.value);
      firebase.auth().createUserWithEmailAndPassword(formData.value.email, formData.value.password)
      .then(function(data) {
        console.log(data);
        if(data){
          a._router.navigate(['/email']);
        }
      }).catch(function(error) {
        console.log(error);
        a.error = error.message;
      });
    }
  }
 
}

Email komponenta

Nalazi se na adresi http://localhost:4200/email s osnovnom svrhom omogućavanja prijave korisnika pomoću e-maila i lozinke.

Angular & Firebase – registracija i prijava

Ekran se sastoji od dva polja za unos e-maila i lozinke.

email.component.html
XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div class="form-container">
  <a routerLink="/login" id="goback">Go back</a>
  <h2>E-mail Login</h2>
 
  <span class="error" *ngIf="error">{{ error }}</span>
 
  <form #formData='ngForm' (ngSubmit)="onSubmit(formData)">
 
    <input type="text" placeholder="E-mail" (ngModel)="email" name="email" class="txt" required>
    <input type="password" placeholder="Password" (ngModel)="password" name="password" class="txt" required>
 
    <button type="submit" [disabled]="!formData.valid" class="basic-btn">Log in</button>
    <a routerLink="/signup" class="alc">Don't have an account?</a>
</form>
</div>

Unosom ispravnih podataka za prijavu korisnik automatski bude preusmjeren na Dashboard dok u suprotnom dobije poruku o grešci.

email.component.ts
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import { Component, OnInit } from '@angular/core';
 
import { AngularFireModule } from 'angularfire2';
import { AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase/app';
import { Router } from '@angular/router';
 
@Component({
  selector: 'app-email',
  templateUrl: './email.component.html',
  styleUrls: ['./email.component.css']
})
export class EmailComponent implements OnInit {
 
  error: any;
 
  constructor(public _angularAuth: AngularFireAuth,
              private _router: Router) { }
 
  ngOnInit() {
  }
 
  onSubmit(formData) {
    let a = this;
    firebase.auth().signInWithEmailAndPassword(formData.value.email, formData.value.password)
    .then(function(data) {
      console.log(data);
      if(data){
        localStorage.setItem('email', data.email);
        a._router.navigate(['/dashboard']);
      }
    }).catch(function(error) {
      console.log(error);
      a.error = error.message;
    });
  }
 
}

Dashboard komponenta

Nalazi se na adresi http://localhost:4200/dashboard s osnovnom svrhom prikaza podataka o korisniku nakon uspješne prijave. U ovom slučaju prikazuje se ime i prezime korisnika, e-mail adresa i slika.

Angular & Firebase – registracija i prijava

Na ekranu se mogu vidjeti podaci o korisniku pod uvjetom (*ngIf) da postoje.

dashboard.component.html
XHTML
1
2
3
4
5
6
7
8
9
10
11
12
<div class="form-container" id="toolbar">
  <header>
    <button (click)="logout()" class="basic-btn">Logout</button>
  </header>
  <div id="page">
    <h2 *ngIf="name">Hey {{name}}!</h2>
    <h6 *ngIf="email">{{email}}</h6>
    <img *ngIf="picture" src="{{picture}}"/>
 
  </div>
  
</div>

Funkcionalnost se sastoji od dohvaćanja podataka o korisniku, funkcije za odjavu koja prazni localStorage i vraća korisnika na početnu stranicu te funkcije za provjeru koja onemogućava korisnike da pristupe Dashboard stranici ako nisu prijavljeni.

dashboard.component.ts
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import { Component, OnInit } from '@angular/core';
 
import { AngularFireModule } from 'angularfire2';
import { AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase/app';
import { Router } from '@angular/router';
 
@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
 
   name: string;
   picture: string;
   email: string;
 
  constructor(public _angularAuth: AngularFireAuth,
              private _router: Router) { }
 
  ngOnInit() {
     this.name = localStorage.getItem('name');
     this.picture = localStorage.getItem('picture');
     this.email = localStorage.getItem('email');
     this.provjera();
  }
 
  logout() {
    //this._angularAuth.auth.logout();
    localStorage.clear();
    console.log('logged out');
    this._router.navigateByUrl('/login');
}
 
provjera(){
   if(!this.email){
    this._router.navigateByUrl('/login');
   }
}
 
 
}

Zaključak

U ovom sam blog postu pokazao kako implementirati Google Firebase prijavu u Angular web projekt.

Angular & Firebase – registracija i prijava

Objavljeno dana 18/03/201805/01/2019Kategorije Frontend, RazvojOznake Angular, Google Firebase, login, prijava, registracijaOstavite komentar na Angular & Firebase – registracija i prijava
Ionic 3 – Google login/prijava

Ionic 3 – Google login/prijava

U ovom ću blog postu pokazati kako na jednostavan način omogućiti prijavu unutar Ionic aplikacije koristeći Google korisničke podatke. Ranije sam već objavio blog post o tome kako se unutar Ionic aplikacije prijaviti koristeći Facebook.

Kreiranje aplikacije

Za početak kreiram novu Ionic aplikaciju i odmah dodajem Android platformu kako bi kasnije mogao aplikaciju pokrenuti na Android mobilnom uređaju.

Shell
1
2
3
$ ionic start IonicPrijavaG blank
$ cd IonicPrijavaG
$ ionic cordova platform add android

Sada ću odmah promijeniti i APP ID oznaku unutar config.xml iz id="io.ionic.starter" u id="hr.tomislavstankovic.ionicprijavag".

Postavljanje Firebase projekta

Temelj za uspješnu Google prijavu je pravilno postavljen Firebase projekt.

Ionic 3 – Google login/prijava

Na poveznici https://developers.facebook.com/apps/ kreiram profil za aplikaciju i pod Authentication – Sign-in providers odabirem Google.

Ionic 3 – Google login/prijava

Ovdje sada imam i Web Client ID koji će mi kasnije trebati unutar funkcije za prijavu.

Ionic 3 – Google login/prijava

SHA-1

Kako je i navedeno na slici iznad, moram kreirati SHA-1. Ovo radim na isti način kao i prilikom pripreme aplikacije za objavu na Google Play Store.

Shell
1
$ keytool -genkey -v -keystore IonicGooglePrijava.keystore -alias IonicGooglePrijava -keyalg RSA -keysize 2048 -validity 10000

Google sign-in is automatically configured on your connected iOS and web apps. To set up Google sign-in for your Android apps, you need to add the SHA1 fingerprint for each app on your Project Settings.

Ionic 3 – Google login/prijava

Sada imam IonicGooglePrijava.keystore datoteku koja je preduvjet za kreiranje SHA-1.

Ionic 3 – Google login/prijava

Kreiranje, produkcijskog, SHA-1 potpisa radi se sljedećom naredbom

Shell
1
2
keytool -exportcert -list -v \
-alias myalias -keystore IonicGooglePrijava.keystore

Ionic 3 – Google login/prijava

Kreiranje, dev, SHA-1 potpisa radi se sljedećom naredbom uz password android

Shell
1
$ keytool -exportcert -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore

Pod Project settings – Your apps klikom na Add Firebase to your Android app radim pripremu za Android verziju Ionic aplikacije.

Ionic 3 – Google login/prijava

Ovdje unosim ranije kreiran SHA-1.

Ionic 3 – Google login/prijava

Implementacija Google prijave

Prije svega moram instalirati Ionic Native Google Plus plugin koristeći sljedeću naredbu

Shell
1
2
$ ionic cordova plugin add cordova-plugin-googleplus --variable REVERSED_CLIENT_ID=myreversedclientid
$ npm install --save @ionic-native/google-plus

U ovom je koraku potreban REVERSED_CLIENT_ID kojega mogu dobiti ako posjetim https://console.developers.google.com/, u izborniku s lijeve strane odaberem API Credentials ili pronaći unutar GoogleService-Info.plist datoteke. To je zapravo obrnuti Web Client ID com.googleusercontent.apps.xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxv

Sada uvozim ranije instaliran plugin unutar app.module.ts

app.module.ts
JavaScript
1
2
3
4
5
6
7
8
import { GooglePlus } from '@ionic-native/google-plus';
...
providers: [
    StatusBar,
    SplashScreen,
    GooglePlus,
    {provide: ErrorHandler, useClass: IonicErrorHandler}
  ]

Ako sada pokrenem aplikaciju vidjet ću samo HomePage stranicu jer sam koristio blank temu i zato ću sada kreirati novu stranicu koja će sadržavati gumb za prijavu. Tek nakon uspješne prijave prikaz će se HomePage stranica.

Shell
1
$ ionic generate page Prijava

Sada ću u app.component.ts postaviti da mi je PrijavaPage početna stranica (rootPage) nakon što se pokrene aplikacija.

app.component.ts
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
 
//import { HomePage } from '../pages/home/home';
 
@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  //rootPage:any = HomePage;
  rootPage:any = 'PrijavaPage';
 
  constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
    platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      statusBar.styleDefault();
      splashScreen.hide();
    });
  }
}

Stranica za prijavu sastojat će se od Ionic loga i gumba za Google prijavu.

prijava.html
XHTML
1
2
3
4
5
6
7
8
9
10
11
12
<ion-content padding>
  <ion-row>
      <ion-col col-12 text-center>
            <img src="assets/imgs/logo.png" alt="Ionic logo" width="250" height="auto">
          </ion-col>
      </ion-row>
            <ion-row padding>
                <ion-col col-12 text-center>
                    <img (click)="prijavaGoogle()" src="assets/imgs/google-button.png" alt="Google logo">
                </ion-col>
              </ion-row>
</ion-content>

Funkcionalnost će se sastojati samo od funkcije za prijavu prijavaGoogle().

prijava.ts
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
 
import { GooglePlus } from '@ionic-native/google-plus';
import { HomePage } from '../home/home';
 
@IonicPage()
@Component({
  selector: 'page-prijava',
  templateUrl: 'prijava.html',
})
export class PrijavaPage {
 
  constructor(public _navCtrl: NavController,
              public _navParams: NavParams,
              public _googlePlus: GooglePlus) {
  }
 
  ionViewDidLoad() {
    console.log('ionViewDidLoad PrijavaPage');
  }
 
  prijavaGoogle(){
    this._googlePlus.login({
      'webClientId': '551660638119-gik6rq06bojtil5f6jijl6aiapet2l6v.apps.googleusercontent.com'
    }).then((res) => {
        console.log(res);
        localStorage.setItem('userEmail', res.email);
        localStorage.setItem('userName', res.displayName);
        localStorage.setItem('userImage', res.imageUrl);
        this._navCtrl.setRoot(HomePage);
    }, (err) => {
        console.log(err);
    });
  }
 
}

console.log(res) izgleda ovako

Ionic 3 – Google login/prijava

Nakon uspješne prijave otvara se početna stranica HomePage na kojoj će se prikazati ime i prezime, slika i e-mail korisnika.

home.html
XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic3 - Google login/prijava
    </ion-title>
  </ion-navbar>
</ion-header>
 
<ion-content padding>
  <ion-list>
    <ion-item>
      <ion-avatar item-start>
        <img src="{{image}}">
      </ion-avatar>
      <h2>{{name}}</h2>
      <p>{{email}}</p>
    </ion-item>
  </ion-list>
</ion-content>

Funkcionalnost HomePage stranice sastoji se od prikaza detalja o korisniku i funkcije za odjavu.

home.ts
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
 
import { GooglePlus } from '@ionic-native/google-plus';
 
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
 
  email: string;
  name: string;
  image: string;
 
  constructor(public _navCtrl: NavController,
              public _googlePlus: GooglePlus) {
  }
 
  ionViewWillEnter(){
    this.email = localStorage.getItem('userEmail');
    this.name = localStorage.getItem('userName');
    this.image = localStorage.getItem('userImage');
  }
 
  logout(){
    this._googlePlus.logout().then(() => {
        console.log("logged out");
        this._navCtrl.setRoot('PrijavaPage');
    });
  }
 
}

Sve to na kraju izgleda ovako

Ionic 3 – Google login/prijava

Zaključak

U ovom sam blog postu pokazao kako na jednostavan i brz način ugraditi Google prijavu unutar Ionic aplikacije.

Struktura projekta prema package.json

package.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
{
  "name": "IonicPrijavaG",
  "version": "0.0.1",
  "author": "Tomislav Stanković",
  "homepage": "https://www.tomislavstankovic.com/",
  "private": true,
  "scripts": {
    "clean": "ionic-app-scripts clean",
    "build": "ionic-app-scripts build",
    "lint": "ionic-app-scripts lint",
    "ionic:build": "ionic-app-scripts build",
    "ionic:serve": "ionic-app-scripts serve"
  },
  "dependencies": {
    "@angular/common": "5.0.3",
    "@angular/compiler": "5.0.3",
    "@angular/compiler-cli": "5.0.3",
    "@angular/core": "5.0.3",
    "@angular/forms": "5.0.3",
    "@angular/http": "5.0.3",
    "@angular/platform-browser": "5.0.3",
    "@angular/platform-browser-dynamic": "5.0.3",
    "@ionic-native/core": "4.4.0",
    "@ionic-native/google-plus": "^4.5.3",
    "@ionic-native/splash-screen": "4.4.0",
    "@ionic-native/status-bar": "4.4.0",
    "@ionic/storage": "2.1.3",
    "cordova-android": "7.0.0",
    "cordova-plugin-device": "^2.0.1",
    "cordova-plugin-googleplus": "^5.2.1",
    "cordova-plugin-ionic-keyboard": "^2.0.5",
    "cordova-plugin-ionic-webview": "^1.1.16",
    "cordova-plugin-splashscreen": "^5.0.2",
    "cordova-plugin-whitelist": "^1.3.3",
    "ionic-angular": "3.9.2",
    "ionicons": "3.0.0",
    "rxjs": "5.5.2",
    "sw-toolbox": "3.6.0",
    "zone.js": "0.8.18"
  },
  "devDependencies": {
    "@ionic/app-scripts": "3.1.8",
    "typescript": "2.4.2"
  },
  "description": "Ionic3 - Google prijava/login",
  "cordova": {
    "plugins": {
      "cordova-plugin-whitelist": {},
      "cordova-plugin-device": {},
      "cordova-plugin-splashscreen": {},
      "cordova-plugin-ionic-webview": {},
      "cordova-plugin-ionic-keyboard": {},
      "cordova-plugin-googleplus": {
        "REVERSED_CLIENT_ID": "com.googleusercontent.apps.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxx"
      }
    },
    "platforms": [
      "android"
    ]
  }
}

Objavljeno dana 11/03/201826/11/2019Kategorije Mobile, RazvojOznake Google Plus, Ionic, Ionic 3, login, prijava2 komentara za Ionic 3 – Google login/prijava

Brojevi stranica objava

Stranica 1 Stranica 2 Sljedeća stranica
Uvjeti korištenja Ponosno pokreće WordPress