-
Notifications
You must be signed in to change notification settings - Fork 12
/
06-adding-users.md.erb
170 lines (128 loc) · 8.35 KB
/
06-adding-users.md.erb
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
---
title: Benutzer hinzufügen
slug: adding-users
date: 0006/01/01
number: 6
contents: Etwas über Benutzerkonten in Meteor lernen.|Authentifizierung für Microscope einrichten.|Das accounts-ui package für das UI einsetzen.
paragraphs: 27
---
Bisher haben wir es geschafft, statische fixture Daten zu kreieren und anzuzeigen und diese in Form eines einfachen Prototypen zusammenzubauen.
Wir haben auch gesehen, dass unser UI sich reaktiv gegenüber Datenänderungen verhält und wie eingefügte or geänderte Daten sofort erscheinen. Weil wir selber aber keine Daten einfügen können, ist unsere Site mehrheitlich nutzlos.
Lass uns sehen wie wir das Problem lösen können.
### Accounts: Benutzerkonten einfach gemacht
In den meisten Web Frameworks ist das Hinzufügen von Benutzerkonten ein mühseliger Vorgang, der jedoch in fast jedem Projekt von Nöten ist. Sobald man sich mit OAuth oder anderen Authentifizierungs-Methoden auseindandersetzen muss, findet man sich schnell im Chaos wieder.
Zum Glück hält Meteor hierfür eine Lösung parat. Dank der Art und Weise wie Meteor packages dem Server (JavaScript) und dem Client (Javascript, HTML und CSS) Code zur Verfügung stellt, erhalten wir ein Benutzerkonten-Sytem zum Nulltarif.
Wir könnten hierfür Meteor's hausgeigenes UI für Benutzerkonten einsetzen (`meteor add accounts-ui`), aber da wir unsere ganze App mit Bootstrap aufgebaut haben, werden wir das `accounts-ui-bootstrap-deopdown` package dafür verwenden. (Keine Bange, der einzige Unterschied ist das unterschiedliche Styling). In der Kommandozeile gebe Folgendes ein:
~~~bash
$ meteor add accounts-ui-bootstrap-dropdown
$ meteor add accounts-password
~~~
<%= caption "Terminal" %>
Diese zwei Befehle stellen uns die Benutzerkonten Templates zur Verfügung. Wir können diese in userer Site mit dem `{{loginButtons}}` helper einfügen. Dazu ein nützlicher Tipp: Du kannst kontrollieren, auf welcher Seite das Log-in Dropdown angezeigt wird, nämlich indem du das `align` Attribut dem helper mitgibst. (Zum Beispiel: `{{loginButtons align="right"}}`)
Wir fügen die Buttons in unseren Header ein. Da dieser immer grösser wird, lagern wir ihn in sein eigenes Template aus (`client/views/includes`). Weiter benutzen wir zusätzlichen Markup und ein paar Bootstrap Klassen um alles schön anschaubar zu machen.
~~~html
<template name="layout">
<div class="container">
{{>header}}
<div id="main" class="row-fluid">
{{yield}}
</div>
</div>
</template>
~~~
<%= caption "client/views/application/layout.html" %>
<%= highlight "6" %>
~~~html
<template name="header">
<header class="navbar">
<div class="navbar-inner">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="{{pathFor 'postsList'}}">Microscope</a>
<div class="nav-collapse collapse">
<ul class="nav pull-right">
<li>{{loginButtons}}</li>
</ul>
</div>
</div>
</header>
</template>
~~~
<%= caption "client/views/includes/header.html" %>
Wenn wir jetzt zu unserer App browsen sehen wir die Login-Buttons in der oberen rechten Ecke unserer Site erscheinen.
<%= screenshot "6-1", "Meteor's built-in accounts UI" %>
Wir können sie für folgende Aktionen benutzen: Anmelden, Einloggen, Passwortänderung und alles was eine einfache Site für Benutzerauthentifizierung braucht.
Um unser Benutzersystem so zu konfigurieren, dass Benutzer sich mit einem Benutzernamen auf unserer Site anmelden müssen, brauchen wir einen `Accounts.ui` Konfigurationsblock in die Datei `config.js` (`client/helpers/`) einzufügen:
~~~js
Accounts.ui.config({
passwordSignupFields: 'USERNAME_ONLY'
});
~~~
<%= caption "client/helpers/config.js" %>
<%= commit "6-1", "Added accounts and added template to the header" %>
### Unseren ersten Benutzer erstellen
Melde nun ein neues Benutzerkonto an: Sobald erfolgt, ändert der Button und zeigt deinen Benutzernamen. Das zeigt auf, dass ein Benutzer für dich angelegt wurde. Aber woher kommt dieses Benutzerkonto?
Mit dem Hinzufügen des `accounts` packages, hat Meteor eine neue spezielle Collection erzeugt, welche mit `Meteor.users` aufgerufen werden kann. Um diese zu überprüfen, öffne die Browser-Konsole und tippe:
~~~js
❯ Meteor.users.findOne();
~~~
<%= caption "Browser console" %>
Die Konsole sollte ein Objekt mit deinem User enthaltend zurückgeben. Wenn du näher hinschaust, kannst du sehen dass sowohl dein Benutzernamen, als auch eine `_id` zur eindeutigen Identifizierung darin enthalten sind. Den gegenwärtig eingeloggten User kannst du auch mit dem Befehl `Meteor.user()` ermitteln.
Logge dich aus und melde ein zweites Benutzerkonto mit einem anderem Benutzernamen an. `Meteor.user()` sollte jetzt einen zweiten Benutzer zurückgeben. Lass uns das überprüfen:
~~~js
❯ Meteor.users.find().count();
1
~~~
<%= caption "Browser console" %>
Die Konsole gibt 1 zurück. Sollten das nicht 2 sein? Wurde der erste Benutzer etwa gelöscht? Wenn du versuchst mit dem ersten Benutzer einzuloggen, siehst du das dies nicht der Fall ist.
Lass uns das verifizieren, indem wir den anerkannten Datenspeicher, die Mongo DB anschauen. Wir loggen in die Mongo DB ein (`meteor mongo` in der Konsole) und überprüfen:
~~~bash
> db.users.count()
2
~~~
<%= caption "Mongo console" %>
Es sind also tatsächlich zwei Benutzer vorhanden. Weshalb können wir im Browser dann nur Einen zur selben Zeit sehen?
### Eine ''Mystery Publication''!
Wenn du zurück an Kapitel 4 denkst, erinnerst du dich vielleicht daran, dass wir mit dem Ausschalten von `autopublish` allen Collections mitteilten, dass sie aufhören sollen automatisch alle Daten vom Server an jeden verbundenen Client in dessen lokale Version der Collection zu senden. Wir mussten eine Publication und eine Subscription erstellen um den Datenaustausch aufrecht zu erhalten.
Doch die Tatsache dass wir nie eine Benutzer Publication erstellt haben, wirft die Frage auf, wie wir dann Benutzerdaten empfangen und darstellen können?
Die Antwort hierfür liegt im accounts package versteckt. Dieses macht eine "Auto-Publikation" des aktuell eingeloggten Benutzers. Würde es dies nicht tun, könnte der Benutzer sich gar nicht erst einloggen.
Das accounts package publiziert allerdings nur den aktuell eingeloggten Benutzer. Das erklärt, wieso ein eingeloggter Benutzer nicht Benutzerkonten-Details eines anderen Benutzers einsehen kann.
Die Publication publiziert also nur ein Benutzer-Objekt (und nichts, wenn du nicht eingeloggt bist).
Weiter noch: Dokumente in unserer Benutzer Collection scheinen nicht dieselben Felder auf dem Server, wie auf dem Client zu beinhalten. In der Mongo-DB hat ein Benutzer viele Datenfelder, welche dem Benutzer-Objekt auf dem Client fehlen. Um dies zu sehen gehe zurück in das Mongo Terminal und tippe:
~~~bash
> db.users.findOne()
{
"createdAt" : 1365649830922,
"_id" : "kYdBd9hr3fWPGPcii",
"services" : {
"password" : {
"srp" : {
"identity" : "qyFCnw4MmRbmGyBdN",
"salt" : "YcBjRa7ArXn5tdCdE",
"verifier" : "df2c001edadf4e475e703fa8cd093abd4b63afccbca48fad1d2a0986ff2bcfba920d3f122d358c4af0c287f8eaf9690a2c7e376d701ab2fe1acd53a5bc3e843905d5dcaf2f1c47c25bf5dd87764d1f58c8c01e4539872a9765d2b27c700dcdedadf5ac82521467356d3f91dbeaf9848158987c6d359c5423e6b9cabf34fa0b45"
}
},
"resume" : {
"loginTokens" : [
{
"token" : "BMHipQqjfLoPz7gru",
"when" : 1365649830922
}
]
}
},
"username" : "tmeasday"
}
~~~
<%= caption "Mongo console" %>
Auf dem Client im Browser ist das Benutzer-Objekt aufs Wesentliche gekürzt. Gib folgende ein:
~~~js
❯ Meteor.users.findOne();
Object {_id: "kYdBd9hr3fWPGPcii", username: "tmeasday"}
~~~
<%= caption "Browser console" %>
Dieses Beispiel zeigt uns wie eine lokale Collection ein sicheres Subset einer Datenbank Collection sein kann. Der eingeloggt Benutzer sieht gerade genug Daten seines gesamten Datensets, um eine Aktion auszuführen (in diesem Fall das Einloggen). Wie wir später noch sehen werden, ist dies ein nützliches Muster von dem du noch viel Lernen kannst.
Dies heisst allerdings nicht, dass es unmöglich ist mehr Benutzerdaten zu publizieren, sofern du das möchtest. Konsultiere die Meteor docs um zu sehen wie du zusätzliche Felder aus der `Meteor.users` Collection publizieren kannst.