Implementirajte svoj SecurityController
Spletna agencija » Digitalne novice » Implementirajte svoj SecurityController

Implementirajte svoj SecurityController

Pred kratkim sem za svoje podjetje napisal članek o upravljanju uporabnikov in njihovem preverjanju pristnosti z izvorno uporabo Symfony2 Core in torej brez FOSUserBundle. Po tem že bogatem prvem članku sem želel opisati enako uporaben drugi del, ki nam bo omogočil hitro nastavitev bistvenih funkcij, in sicer ponastavitev gesla, spremembo gesla, potrditev računa ali celo registracijo. Dejanja so prav tako pomembna, ko imate sistem za upravljanje uporabnikov.

Nastavite SecurityController

Najprej, če še niste sledili prvi vadnici o nastavitvi upravljanja uporabnikov, vam svetujem, da si ogledate. Če ste sledili rešitvi, bi logično morali imeti SecurityController ali kaj drugega. V mojem primeru imam samo tri metode, od katerih je le ena res uporabna.

  1. loginAction
    Ta metoda povezuje uporabnika.
  2. checkAction
    Ta metoda vam preprosto omogoča, da deklarirate pot za požarni zid, kar uporabniku omogoča povezavo na strani strežnika.
  3. odjavaAction
    Ta metoda se uporablja za deklaracijo poti za požarni zid, ki uporabniku omogoča prekinitev povezave.

Odprite našo platformo novim uporabnikom

Posebej zanimivo bi bilo, če bi se naši uporabniki lahko povezali in se torej predhodno registrirali.

Najprej ustvarimo obrazec s podatki, ki jih želite vprašati svojega uporabnika.

Glede obrazca, ki ga boste uporabili za registracijo svojega uporabnika, vedi, da polje " geslo ne sme biti v vaši obliki. Vendar boste morali dodati dve polji " ni preslikano da dvakrat vnesete želeno geslo.

1
2
3
4
5
6
7
8
9
10
11
12
13
/ **
 * @Metoda({“GET”})
 * @Cesta(“/register”, ime=”register”)
 * @Varno(vloge=”IS_AUTHENTICATED_ANONYMOUSLY”)
 * @Predloga()
 */
javnega funkcija Registracija()
{
    $obrazec = $ to->createForm(novo UserType(UserType::REGISTER), novo Uporabnik());
    vrnitev matrika(
        "oblika" => $form->createView(),
        );
}

Potem, ko se vaš uporabnik vrne z izpolnjenim obrazcem, ga bomo morali registrirati ali zavrniti njegovo datoteko :p

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
/ **
* @Metoda({“POST”})
* @Cesta(»/register«)
* @Varno(vloge=”IS_AUTHENTICATED_ANONYMOUSLY”)
* @Predloga()
*/
javnega funkcija Registriraj se zdaj(Zahteva $request)
{
$params = $request->request->all()[“ime_mojega_obrazca”];
$obrazec = $ to->createForm(novo UserType(UserType::REGISTER), novo Uporabnik());
$form->submit($request);
if (matrični_ključ_obstaja(“navadno_geslo”, $params) && array_key_exists("navadno_geslo2", $params) && $params[“navadno_geslo”] == $params["navadno_geslo2"]) {
if ($form->isValid()) {
$data = $form->getData();
$data->setPassword($ to->vsebnik->dobi(“security.encoder_factory”)->getEncoder($data)->encodePassword($params[“navadno_geslo”], $data->getSalt()));
$em->vztrajati($podatki);
$em->flush();
vrnitev $ to->preusmeri($ to->generateUrl("Vpiši se", matrika("sporočilo" => »Prejeli ste e-poštno sporočilo za potrditev računa. »)));
}
}
vrnitev matrika(
"napake" => $params[“navadno_geslo”] == $params["navadno_geslo2"]? $form->getErrors(): matrika("Gesli morata biti enaki"),
"oblika" => $form->createView(),
);
}

Tukaj bomo na hitro podrobno opisali potek dela za registracijo novega uporabnika.

  1. Gledamo če so vsa zahtevana polja pravilno vpisana, vključno z obema poljema »geslo« in če sta zadnji dve enaki.
  2. Geslo kodiramo in ga »nastavimo« v entiteto.
  3. V primeru kakršne koli napake, vrnemo obrazec z napako, za katero menimo, da bi morala biti podrobna.

Ustvarite funkcijo za ponastavitev gesla

Zdaj se lahko vaš uporabnik prijavi, a kaj bomo storili, če izgubi geslo. Očitno je, da ne bomo vzpostavili kontaktnega e-poštnega naslova, namenjenega njegovim nekoristnim operacijam.

Kot ste videli zgoraj, običajno deklariram dve metodi za vsako od svojih funkcij: ena od mojih metod je odgovorna za upravljanje pogleda, ustvarjenega po zahtevi GET in rezultat zahteve POST. Ti dve metodi lahko absolutno združite v eno in isto metodo.

1
2
3
4
5
6
7
8
9
/ **
  * @Metoda({“GET”})
  * @Cesta(“/reset”, name=”reset”)
  * @Varno(vloge=”IS_AUTHENTICATED_ANONYMOUSLY”)
  * @Predloga()
  */
  javnega funkcija ponastavitev() {
   vrnitev matrika();
  }

V drugem koraku bomo razglasili komplementarno metodo za upravljanje zahtev POST.

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
/ **
* @Metoda({“POST”})
* @Cesta("/ponastaviti")
* @Varno(vloge=”IS_AUTHENTICATED_ANONYMOUSLY”)
*/
javnega funkcija resetNow(Zahteva $request)
{
$params = $request->request->all();
if (!array_key_exists("Vpiši se", $params)) {
met novo Izjema(»Prijava ni podana«);
}
$login = &$params["Vpiši se"];
$em = $ to->vsebnik->dobi(“doctrine.orm.default_entity_manager”);
$user = $em->getRepository(»NamespaceMyBundle:Uporabnik«)->findOneBy(matrika("Vpiši se" => $prijava));
if ($uporabnik == null) {
vrnitev $ to->preusmeri($ to->generateUrl("Vpiši se", matrika()));
}
$geslo = “myRandowPassword”;
$user->setPassword($ to->vsebnik->dobi(“security.encoder_factory”)->getEncoder($user)->encodePassword($password, $user->getSalt()));
$em->vztrajati($uporabnik);
$em->flush();
// Geslo pošljemo po elektronski pošti
vrnitev $ to->preusmeri($ to->generateUrl("Vpiši se", matrika()));
}

Ta metoda je bila zasnovana za ponastaviti geslo uporabnika, ki je posredoval svoje prijava/uporabniško ime. V mojem primeru je bilo geslo nato poslano po e-pošti. Dovolim vam, da dodate to galantno vrstico.

  1. Torej gremo iskalni uporabnik.
  2. Ustvarimo geslo da uporabnika obvestimo, ko se je kodiral po pravilih, ki ste jih določili.

Nastavite spremembo gesla

Na tej točki lahko naš uporabnik ustvari novo geslo, če je bilo izgubljeno, če pa ga želi le spremeniti, potrebujemo vrata za določitev vrat.

1
2
3
4
5
6
7
8
9
/ **
* @Metoda({“GET”})
* @Cesta(“/sprememba”, ime=”sprememba gesla”)
* @Varno(vloge=”IS_AUTHENTICATED_FULLY”)
* @Predloga()
*/
javnega funkcija spremenite() {
vrnitev matrika();
}

Tukaj je koda za ustvarjanje pogleda. Najprej boste morali vnesti svoje staro geslo, nato dvakrat vnesti novo geslo. Drugič je potrditev.

Zdaj bomo videli kodo za ponastavilec geslo. THE Postopek je podobno generiranju novega naključnega gesla.

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
/ **
 * @Metoda({“POST”})
 * @Cesta(»/sprememba«)
 * @Varno(vloge=”IS_AUTHENTICATED_FULLY”)
 * @Predloga()
 */
javnega funkcija spremeni zdaj(Zahteva $request)
{
    $params = $request->request->all();
    if (!array_key_exists(“trenutno”, $params)
        || !array_key_exists(“novo”, $params)
        || !array_key_exists(“novo2”, $params))
    {
        vrnitev matrika(“napaka” => “Prosimo, izpolnite vsa polja”);
    }
    $em = $ to->vsebnik->dobi(“doctrine.orm.default_entity_manager”);
    $uporabnik = $ to->getUser();
    $user_encoders = $ to->vsebnik->dobi(“security.encoder_factory”)->getEncoder($user);
    $user_repository = $em->getRepository(»NamespaceMyBundle:Uporabnik«);
    $current_password_encoded = $user_encoders->encodePassword($params[“trenutno”], $user->getSalt());
    $new_password_encoded = $user_encoders->encodePassword($params[“novo”], $user->getSalt());
    if ($user_repository->findOneBy(matrika("geslo" => $current_password_encoded)) == null) {
        vrnitev matrika(“napaka” => »Trenutno geslo je napačno«);
    } drugače ($params[“novo”] != $params[“novo2”]) {
        vrnitev matrika(“napaka” => "Dve polji gesla nista enaki");
    }
    $user->setPassword($new_password_encoded);
    $em->vztrajati($uporabnik);
    $em->flush();
    vrnitev $ to->preusmeri($ to->generateUrl("Odjava", matrika()));
}

Če si vzamete 1 minuto časa in preberete kodo, boste videli, da je ta še posebej preprosta.

  1. Najprej preverimo, ali so tri polja (staro geslo, novo geslo in potrditev) pravilno vpisana.
  2. On vnesite geslo trenutni in ga primerjamo s trenutnim geslomv bazi podatkov, da preverite, ali se ujema s starim vnesenim geslom.
  3. Preverimo, ali sta "dve" novi gesli identična.
  4. Vnesite novo geslo in potisnite v entiteti.

Aktivacija njegovega računa

Ta funkcija ni popolnoma podrobno opisana v drugih odrezke nad. Njegov namen je odblokirati uporabnika, ki se je pravkar registriral, ko je na primer potrdil svojo e-pošto. Ta funkcionalnost je razvita na skoraj vseh platformah, ki jih poznamo iz več razlogov. Če želite nastaviti blokiranje uporabnika, boste morda morali implementirati tudi ponudnika.

  • blok/omejitev računov ponaredek in spam.
  • Preveritelj da je uporabnik izpolnil e-poštni naslov, ki je na prvi pogled videti uporaben.
  • Odstrani računi, ki po določenem času niso bili potrjeni.

Potek dela

  1. Uporabnik se registrira. Njegov račun je nato blokiran prek posebnega polja. To polje bi mu moralo preprečiti povezavo, dokler to polje označuje, da je račun onemogočen.
1
2
3
4
5
6
7
8
// NamespaceMyBundleEntityUser
razred uporabnik {
javnega funkcija __konstruirati() {
$ to->token = hash(“sha512”, uniqid());
}
...
}
1
$user->setEnabled(false);
  1. Uporabnik je prejel elektronsko sporočilo, ko je bil njegov profil splakniti v bazi podatkov. Ta e-pošta mora biti del naslova, ki ga ustvarite.
    Na tej cesti je a token ali mora biti podana edinstvena identifikacijska oznaka, ki omogoča iskanje zadevnega uporabnika. Svetujem vam, da uporabite UUID4, ki naj bi bil naključen. Najdete lahko seznam UUID-jev in opise vseh različic.
1
2
3
4
/ **
* @Cesta(“/aktiviraj”, ime=”aktiviraj”)
*/
javnega funkcija aktivira() {…}
1
$ to->generateUrl("aktiviraj", matrika(« token » => $user->getToken()), Res);

Morali bi imeti tak URL.

1
http://ime gostitelja/aktivirati?token=myUniqueToken
  1. Uporabnik odpre svojo e-pošto in poskuša aktivirati svoj račun s klikom na navedeno povezavo. Nato vstopimo v spodnji postopek.
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
/ **
 * @Metoda({“GET”})
 * @Cesta(“/aktiviraj”, ime=”aktiviraj”)
 * @Varno(vloge=”IS_AUTHENTICATED_ANONYMOUSLY”)
 * @Predloga()
 */
javnega funkcija aktivira(Zahteva $request) {
    $params = matrika();
    $token = $request->query->get(« token »);
    $em = $ to->vsebnik->dobi(“doctrine.orm.default_entity_manager”);
$user = $em->getRepository(»NamespaceMyBundle:Uporabnik«)->findOneBy(matrika(« token » => $token));
    if ($uporabnik != null) {
        $user->setEnabled(Res);
        $em->vztrajati($uporabnik);
        $em->flush();
        $params["aktiviraj"] = Res;
    } ostalo {
        $params["aktiviraj"] = false;
    }
    vrnitev $params;
}

S tem postopkom ne bi smeli imeti težav z omogočanjem preverjanja uporabniškega računa na mestu.

To enakovredno kodo najdete na tem Gist-u.

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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
uporaba JMSSecurityExtraBundleOpombaVarnost;
uporaba SensioSveženjFrameworkExtraBundlekonfiguracijaMetoda;
uporaba SensioSveženjFrameworkExtraBundlekonfiguracijaPot;
uporaba SensioSveženjFrameworkExtraBundlekonfiguracijapredloga;
uporaba SimfonijaSveženjFrameworkBundlekrmilnikkrmilnik;
uporaba SimfonijaSestavinaHttpFoundationZahteva;
uporaba SimfonijaSestavinaVarnostCoreVarnostni kontekst;
razred SecurityController Se razširi krmilnik
{
/ **
* @Metoda({“GET”})
* @Cesta(“/prijava”, ime=”prijava”)
* @Predloga()
*/
javnega funkcija prijava(Zahteva $request)
{
$request= $ to->getRequest();
$session = $request->getSession();
if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $request->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
} ostalo {
$error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
$session->remove(SecurityContext::AUTHENTICATION_ERROR);
}
$params = matrika(
“last_username” => $session->get(SecurityContext::LAST_USERNAME),
“napaka” => $napaka,
"sporočilo" => $request->get("sporočilo"),
);
if ($request->isXmlHttpRequest()) {
vrnitev $ to-> upodabljanje (“GCDirectoryMainBundle:Security:login-ajax.html.twig”, $params);
}
vrnitev $params;
}
/ **
* @Metoda({“POST”})
* @Cesta(“/login_check”, name=”login_check”)
*/
javnega funkcija preveriti()
{
met novo RuntimeException ('Konfigurirati morate pot preverjanja, ki jo bo obravnaval požarni zid, z uporabo form_login v konfiguraciji varnostnega požarnega zidu.');
}
/ **
* @Metoda({“GET”})
* @Cesta(“/odjava”, ime=”odjava”)
*/
javnega funkcija logout()
{
met novo RuntimeException ('Odjavo morate aktivirati v konfiguraciji varnostnega požarnega zidu.');
}
/ **
* @Metoda({“GET”})
* @Cesta(“/reset”, name=”reset”)
* @Varno(vloge=”IS_AUTHENTICATED_ANONYMOUSLY”)
* @Predloga()
*/
javnega funkcija ponastavitev() {
vrnitev matrika();
}
/ **
* @Metoda({“POST”})
* @Cesta("/ponastaviti")
* @Varno(vloge=”IS_AUTHENTICATED_ANONYMOUSLY”)
*/
javnega funkcija resetNow(Zahteva $request)
{
$params = $request->request->all();
if (!array_key_exists("Vpiši se", $params)) {
met novo Izjema(»Prijava ni podana«);
}
$login = &$params["Vpiši se"];
$em = $ to->vsebnik->dobi(“doctrine.orm.default_entity_manager”);
$user = $em->getRepository(»NamespaceMyBundle:Uporabnik«)->findOneBy(matrika("Vpiši se" => $prijava));
if ($uporabnik == null) {
vrnitev $ to->preusmeri($ to->generateUrl("Vpiši se", matrika()));
}
$geslo = “myRandowPassword”;
$user->setPassword($ to->vsebnik->dobi(“security.encoder_factory”)->getEncoder($user)->encodePassword($password, $user->getSalt()));
$em->vztrajati($uporabnik);
$em->flush();
vrnitev $ to->preusmeri($ to->generateUrl("Vpiši se", matrika()));
}
/ **
* @Metoda({“GET”})
* @Cesta(“/sprememba”, ime=”sprememba gesla”)
* @Varno(vloge=”IS_AUTHENTICATED_FULLY”)
* @Predloga()
*/
javnega funkcija spremenite() {
vrnitev matrika();
}
/ **
* @Metoda({“POST”})
* @Cesta(»/sprememba«)
* @Varno(vloge=”IS_AUTHENTICATED_FULLY”)
* @Predloga()
*/
javnega funkcija spremeni zdaj(Zahteva $request)
{
$params = $request->request->all();
if (!array_key_exists(“trenutno”, $params)
|| !array_key_exists(“novo”, $params)
|| !array_key_exists(“novo2”, $params))
{
vrnitev matrika(“napaka” => “Prosimo, izpolnite vsa polja”);
}
$em = $ to->vsebnik->dobi(“doctrine.orm.default_entity_manager”);
$uporabnik = $ to->getUser();
$user_encoders = $ to->vsebnik->dobi(“security.encoder_factory”)->getEncoder($user);
$user_repository = $em->getRepository(»NamespaceMyBundle:Uporabnik«);
$current_password_encoded = $user_encoders->encodePassword($params[“trenutno”], $user->getSalt());
$new_password_encoded = $user_encoders->encodePassword($params[“novo”], $user->getSalt());
if ($user_repository->findOneBy(matrika("geslo" => $current_password_encoded)) == null) {
vrnitev matrika(“napaka” => »Trenutno geslo je napačno«);
} drugače ($params[“novo”] != $params[“novo2”]) {
vrnitev matrika(“napaka” => "Dve polji gesla nista enaki");
}
$user->setPassword($new_password_encoded);
$em->vztrajati($uporabnik);
$em->flush();
vrnitev $ to->preusmeri($ to->generateUrl("Odjava", matrika()));
}
/ **
* @Metoda({“GET”})
* @Cesta(“/register”, ime=”register”)
* @Varno(vloge=”IS_AUTHENTICATED_ANONYMOUSLY”)
* @Predloga()
*/
javnega funkcija Registracija()
{
$obrazec = $ to->createForm(novo UserType(UserType::REGISTER), novo Uporabnik());
vrnitev matrika(
"oblika" => $form->createView(),
);
}
/ **
* @Metoda({“POST”})
* @Cesta(»/register«)
* @Varno(vloge=”IS_AUTHENTICATED_ANONYMOUSLY”)
* @Predloga()
*/
javnega funkcija Registriraj se zdaj(Zahteva $request)
{
$params = $request->request->all()[“ime_mojega_obrazca”];
$obrazec = $ to->createForm(novo UserType(UserType::REGISTER), novo Uporabnik());
$form->submit($request);
if (matrični_ključ_obstaja(“navadno_geslo”, $params) && array_key_exists("navadno_geslo2", $params) && $params[“navadno_geslo”] == $params["navadno_geslo2"]) {
if ($form->isValid()) {
$data = $form->getData();
$data->setPassword($ to->vsebnik->dobi(“security.encoder_factory”)->getEncoder($data)->encodePassword($params[“navadno_geslo”], $data->getSalt()));
$em->vztrajati($podatki);
$em->flush();
vrnitev $ to->preusmeri($ to->generateUrl("Vpiši se", matrika("sporočilo" => »Prejeli ste e-poštno sporočilo za potrditev računa. »)));
}
}
vrnitev matrika(
"napake" => $params[“navadno_geslo”] == $params["navadno_geslo2"]? $form->getErrors(): matrika("Gesli morata biti enaki"),
"oblika" => $form->createView(),
);
}
/ **
* @Metoda({“GET”})
* @Cesta(“/aktiviraj”, ime=”aktiviraj”)
* @Varno(vloge=”IS_AUTHENTICATED_ANONYMOUSLY”)
* @Predloga()
*/
javnega funkcija aktivira(Zahteva $request) {
$params = matrika();
$token = $request->query->get(« token »);
$em = $ to->vsebnik->dobi(“doctrine.orm.default_entity_manager”);
$user = $em->getRepository(»NamespaceMyBundle:Uporabnik«)->findOneBy(matrika(« token » => $token));
if ($uporabnik != null) {
$user->setActive(Uporabnik::ACTIVE_ACTIVE);
$em->vztrajati($uporabnik);
$em->flush();
$params["aktiviraj"] = Res;
} ostalo {
$params["aktiviraj"] = false;
}
vrnitev $params;
}
}

★ ★ ★ ★ ★