տուն Ատամների բուժում Գրեք գրանցումը php-ում։ Օգտագործողի գրանցման պարզ համակարգ

Գրեք գրանցումը php-ում։ Օգտագործողի գրանցման պարզ համակարգ

Բարեւ Ձեզ! Այժմ մենք կփորձենք իրականացնել ամենապարզ գրանցումը կայքում՝ օգտագործելով PHP + MySQL: Դա անելու համար Apache-ը պետք է տեղադրված լինի ձեր համակարգչում: Մեր սցենարի աշխատանքի սկզբունքը ներկայացված է ստորև։

1. Սկսենք տվյալների բազայում օգտվողների աղյուսակ ստեղծելուց: Այն կպարունակի օգտվողի տվյալներ (մուտք և գաղտնաբառ): Եկեք գնանք phpmyadmin (եթե դուք ստեղծում եք տվյալների բազա ձեր համակարգչի վրա http://localhost/phpmyadmin/) Մենք ստեղծում ենք օգտվողների աղյուսակ, այն կունենա 3 դաշտ:

Ես այն ստեղծում եմ mysql տվյալների բազայում, դուք կարող եք այն ստեղծել այլ տվյալների բազայում։ Հաջորդը, սահմանեք արժեքները, ինչպես նկարում.

2. Պահանջվում է միացում այս աղյուսակին: Եկեք ստեղծենք bd.php ֆայլ: Դրա բովանդակությունը.

Իմ դեպքում դա այսպիսի տեսք ունի.

Պահպանել bd.php.
Հիանալի Տվյալների բազայում ունենք աղյուսակ և դրա հետ կապ: Այժմ դուք կարող եք սկսել ստեղծել էջ, որի վրա օգտվողները կթողնեն իրենց տվյալները:

3. Ստեղծեք reg.php ֆայլ բովանդակությամբ (բոլոր մեկնաբանությունները ներսում).



Գրանցում


Գրանցում


Ձեր մուտքը.




Քո գաղտնաբառը:








4. Ստեղծեք ֆայլ, որը տվյալների բազա կմտնի և կփրկի օգտատիրոջը: save_user.php (մեկնաբանություններ ներսում):

5. Այժմ մեր օգտվողները կարող են գրանցվել: Հաջորդը, դուք պետք է ստեղծեք «դուռ» արդեն գրանցված օգտվողների համար կայք մուտք գործելու համար: index.php (մենաբանություններ ներսում):




Գլխավոր էջ


Գլխավոր էջ


Ձեր մուտքը.


Քո գաղտնաբառը:






Գրանցվել



Լավ, հիմա ամեն ինչ ավարտված է: Դասը կարող է ձանձրալի լինել, բայց շատ օգտակար։ Այստեղ ցուցադրվում է միայն գրանցման գաղափարը, այնուհետև կարող եք բարելավել այն՝ ավելացնել անվտանգություն, դիզայն, տվյալների դաշտեր, բեռնել ավատարներ, դուրս գալ ձեր հաշվից (դա անելու համար պարզապես ջնջեք փոփոխականները նիստից չսահմանված ֆունկցիայով) և այսպես շարունակ։ Հաջողություն!

Ես ամեն ինչ ստուգեցի, ճիշտ է աշխատում:

Այսօր մենք կանդրադառնանք հանրաճանաչ CMS Joomla-ում 1-օրյա կարևոր խոցելիության շահագործմանը, որը հոկտեմբերի վերջին պայթեց համացանցում: Մենք կխոսենք խոցելիության մասին CVE-2016-8869, CVE-2016-8870 և CVE-2016-9081 համարներով: Երեքն էլ գալիս են մեկ կոդից, որը հինգ երկար տարիներ մնաց շրջանակի խորքերում՝ սպասելով թեւերի մեջ, հետո միայն ազատ արձակվի և իր հետ բերի քաոս, կոտրված կայքեր և այս Joomla-ի անմեղ օգտատերերի արցունքները: Միայն ամենախիզախ և խիզախ մշակողները, որոնց աչքերը կարմիր են մոնիտորների լույսից, և որոնց ստեղնաշարերը լցված են հացի փշրանքներով, կարողացան մարտահրավեր նետել կատաղի չար ոգիներին և իրենց գլուխները դնել շտկման զոհասեղանի վրա:

ԶԳՈՒՇԱՑՈՒՄ Ամբողջ տեղեկատվությունը տրամադրվում է միայն տեղեկատվական նպատակներով: Ոչ խմբագիրները, ոչ հեղինակը պատասխանատվություն չեն կրում սույն հոդվածի նյութերի պատճառած հնարավոր վնասի համար: Այնտեղ, որտեղ ամեն ինչ սկսվեց

2016 թվականի հոկտեմբերի 6-ին Դեմիս Պալման Stack Exchange-ում ստեղծեց մի թեմա, որտեղ նա հարցրեց. իրականում ինչո՞ւ Joomla-ի 3.6 տարբերակում կա նույնանուն ռեգիստր() օգտվողներին գրանցելու երկու եղանակ: Առաջինը UsersControllerRegistration վերահսկիչում է, իսկ երկրորդը՝ UsersControllerUser վերահսկիչում։ Դամիսը ցանկանում էր իմանալ՝ UsersControllerUser::register() մեթոդը ինչ-որ տեղ օգտագործվե՞լ է, թե՞ դա պարզապես հին տրամաբանությունից մնացած էվոլյուցիոն անախրոնիզմ է։ Նրա մտահոգությունն այն էր, որ նույնիսկ եթե այս մեթոդը չի օգտագործվում որևէ տեսակետի կողմից, այն կարող է կոչվել մշակված հարցումով: Ինչին ես պատասխան ստացա իկտոպուս մականունով ծրագրավորողից, որը հաստատեց՝ խնդիրն իսկապես կա։ Եվ հաշվետվություն ուղարկեց Joomla-ի մշակողներին:

Հետո իրադարձություններն ամենաարագ զարգացան։ Հոկտեմբերի 18-ին Joomla-ի մշակողները ընդունեցին Damis-ի զեկույցը, որն այդ ժամանակ մշակել էր PoC-ի նախագիծ, որը թույլ կտա գրանցել օգտվողներին: Նա գրություն է հրապարակել իր կայքում, որտեղ ընդհանուր առմամբ խոսել է իր գտած խնդրի և այս հարցի վերաբերյալ իր մտքերի մասին։ Նույն օրը թողարկվում է Joomla 3.6.3-ի նոր տարբերակը, որը դեռ պարունակում է խոցելի կոդ։

Սրանից հետո Դավիդե Տամպելինին սխալը պտտեցնում է այնքան, որ գրանցում է ոչ թե պարզ օգտատեր, այլ ադմինիստրատոր։ Իսկ հոկտեմբերի 21-ին նոր դեպք է հասնում Joomla-ի անվտանգության թիմին։ Այն արդեն խոսում է արտոնությունների ավելացման մասին։ Նույն օրը Joomla-ի կայքում հայտնվում է հայտարարություն այն մասին, որ երեքշաբթի՝ հոկտեմբերի 25-ին, կթողարկվի հաջորդ տարբերակը՝ 3.6.3 սերիական համարով, որը շտկում է համակարգի միջուկի կրիտիկական խոցելիությունը։

Հոկտեմբերի 25 Joomla Security Strike Team-ը գտնում է Damis-ի կողմից հայտնաբերված կոդի կտորի կողմից ստեղծված վերջին խնդիրը: Այնուհետև հոկտեմբերի 21-ով թվագրված հանձնարարությունը՝ Prepare 3.6.4 Stable Release աննկատ անունով, դրվում է Joomla-ի պաշտոնական պահեստի հիմնական մասնաճյուղ, որն ուղղում է դժբախտ սխալը:

Այս հրապարակումից հետո բազմաթիվ շահագրգիռ անհատներ միանում են ծրագրավորողների համայնքին. նրանք սկսում են խթանել խոցելիությունը և պատրաստել շահագործում:

Հոկտեմբերի 27-ին հետազոտող Հարրի Ռոբերթսը Xiphos Research-ի պահոց է վերբեռնում պատրաստի շահագործում, որը կարող է PHP ֆայլ վերբեռնել խոցելի CMS-ով սերվերի վրա:

Մանրամասներ

Դե, ֆոնն ավարտված է, անցնենք ամենահետաքրքիր մասին՝ խոցելիության վերլուծությանը։ Ես տեղադրել եմ Joomla 3.6.3-ը որպես փորձնական տարբերակ, այնպես որ բոլոր տողերի համարները համապատասխան կլինեն այս տարբերակի համար: Եվ ֆայլերի բոլոր ուղիները, որոնք դուք կտեսնեք ստորև, կնշվեն տեղադրված CMS-ի արմատի համեմատ:

Դեմիս Պալմայի հայտնագործության շնորհիվ մենք գիտենք, որ կա երկու մեթոդ, որոնք իրականացնում են օգտատերերի գրանցումը համակարգում։ Առաջինն օգտագործվում է CMS-ի կողմից և գտնվում է /components/com_users/controllers/registration.php:108 ֆայլում: Երկրորդը (նա, ում պետք է կանչենք) ապրում է /components/com_users/controllers/user.php:293-ում: Եկեք մանրամասն նայենք դրան:

286: /** 287: * Օգտատիրոջ գրանցման եղանակ: 288: * 289: * @return բուլյան 290: * 291: * @ince 1.6 292: */ 293: հանրային գործառույթի գրանցում () 294: ( 295: JSession::checkToken ("post") կամ jexit (JText::_ («JINVALID_TOKEN»)); ... 300: // Ստացեք ձևի տվյալները: 301: $data = $this->input->post->get("user", array(), "array"); . .. 315: $return = $model->validate($form, $data); 316: 317: // Ստուգեք սխալների համար: 318: if ($return === false) 319: ( ... 345: / / Ավարտեք գրանցումը 346. $return = $model->register($data);

Այստեղ ես թողեցի միայն հետաքրքիր տողեր. Խոցելի մեթոդի ամբողջական տարբերակը կարելի է դիտել Joomla-ի պահոցում:

Եկեք պարզենք, թե ինչ է տեղի ունենում օգտատերերի սովորական գրանցման ժամանակ՝ ինչ տվյալներ են ուղարկվում և ինչպես են դրանք մշակվում: Եթե ​​օգտատիրոջ գրանցումը միացված է կարգավորումներում, ձևը կարելի է գտնել http://joomla.local/index.php/component/users/?view=registration կայքում:


Օգտատիրոջ գրանցման օրինական հարցումը նման է հետևյալ սքրինշոթին:


com_users բաղադրիչը պատասխանատու է օգտատերերի հետ աշխատելու համար: Ուշադրություն դարձրեք հարցման մեջ առաջադրանքի պարամետրին: Այն ունի $controller.$method ձևաչափը: Եկեք նայենք ֆայլի կառուցվածքին:

Կարգավորիչների թղթապանակում սկրիպտների անունները համապատասխանում են կանչված կարգավորիչների անուններին: Քանի որ մեր հարցումն այժմ ունի $controller = "registration" , կկանչվեն register.php ֆայլը և դրա register() մեթոդը:

Ուշադրություն, հարց՝ ինչպե՞ս փոխանցել գրանցման գործընթացը կոդի խոցելի տեղ։ Դուք հավանաբար արդեն գուշակել եք դա։ Խոցելի և իրական մեթոդների անվանումները նույնն են (գրանցվել), այնպես որ մենք պարզապես պետք է փոխենք կանչված վերահսկիչի անունը։ Որտե՞ղ է գտնվում մեր խոցելի վերահսկիչը: Ճիշտ է, user.php ֆայլում: Ստացվում է $controller = "user" . Ամեն ինչ միացնելով մենք ստանում ենք task = user.register : Այժմ գրանցման հարցումը մշակվում է մեզ անհրաժեշտ մեթոդով:


Երկրորդ բանը, որ մենք պետք է անենք, տվյալները ճիշտ ձևաչափով ուղարկելն է: Այստեղ ամեն ինչ պարզ է. Legitimate register()-ը մեզանից ակնկալում է jform կոչվող զանգված, որում մենք փոխանցում ենք գրանցման տվյալները՝ անունը, մուտքի անունը, գաղտնաբառը, էլ.

  • /components/com_users/controllers/registration.php: 124: // Ստացեք օգտվողի տվյալները: 125. $requestData = $this->input->post->get("jform", array(), "array");

Մեր հաճախորդը ստանում է այս տվյալները օգտագործող կոչվող զանգվածից:

  • /components/com_users/controllers/user.php: 301: // Ստացեք ձևի տվյալները: 302. $data = $this->input->post->get("user", array(), "array");

Հետևաբար, մենք հարցումում բոլոր պարամետրերի անունները փոխում ենք jfrom-ից օգտվողի:

Մեր երրորդ քայլը վավեր CSRF նշան գտնելն է, քանի որ առանց դրա գրանցում չի լինի:

  • /components/com_users/controllers/user.php: 296: JSession::checkToken("post") կամ jexit(JText::_("JINVALID_TOKEN"));

Այն կարծես MD5 հեշ լինի, և դուք կարող եք այն վերցնել, օրինակ, /index.php/component/users/?view=login կայքի թույլտվության ձևից:


Այժմ դուք կարող եք ստեղծել օգտվողներ, օգտագործելով ցանկալի մեթոդը: Եթե ​​ամեն ինչ աշխատեց, ապա շնորհավորում ենք. դուք պարզապես շահագործել եք CVE-2016-8870 «բացակայող թույլտվության ստուգումը նոր օգտվողների գրանցման համար» խոցելիությունը:

Ահա թե ինչ տեսք ունի UsersControllerRegistration վերահսկիչի «աշխատանքային» ռեգիստր () մեթոդում.

  • /components/com_users/controllers/registration.php: 113: // Եթե գրանցումն անջատված է - Վերահղում դեպի մուտքի էջ: 114: եթե (JComponentHelper::getParams("com_users")->get("allowUserRegistration") == 0) 115: (116: $this->setRedirect(JRoute::_("index.php?option=com_users&view= մուտք», կեղծ)); 117: 118: վերադարձ կեղծ; 119: )

Եվ այսպես, խոցելի վիճակում.

  • /components/com_users/controllers/user.php:

Այո, ոչ մի կերպ:

Երկրորդ, շատ ավելի լուրջ խնդիրը հասկանալու համար ուղարկենք մեր ստեղծած հարցումը և տեսնենք, թե ինչպես է այն կատարվում կոդի տարբեր մասերում։ Ահա այն հատվածը, որը պատասխանատու է աշխատողի մեթոդով օգտագործողի կողմից ներկայացված տվյալների վավերացման համար.

Շարունակությունը հասանելի է միայն անդամներին Տարբերակ 1. Միացեք «կայքի» համայնքին՝ կայքի բոլոր նյութերը կարդալու համար

Նշված ժամանակահատվածում համայնքին անդամակցությունը ձեզ հնարավորություն կտա մուտք գործել ԲՈԼՈՐ Հաքերային նյութերը, կավելացնի ձեր անձնական կուտակային զեղչը և թույլ կտա ձեզ կուտակել պրոֆեսիոնալ Xakep Score վարկանիշ:

Laravel-ը Կոմպոզիտորից պահանջում է կառավարել նախագծի կախվածությունները: Այսպիսով, Laravel-ը տեղադրելուց առաջ համոզվեք, որ ձեր համակարգում տեղադրված է Composer-ը: Եթե ​​առաջին անգամ եք լսում Կոմպոզիտորի մասին, ապա դա php-ի համար կախվածության կառավարման գործիք է, որը նման է հանգույցի npm-ին:

Composer-ը ձեր մեքենայի վրա տեղադրելու համար ստուգեք այս գրառումը.

Laravel-ի տեղադրում Windows-ում.

Windows մեքենայի վրա laravel-ը տեղադրելու համար հետևեք ստորև նշված քայլերին: Անկախ նրանից, որ դուք ունեք xampp/wamp stack, այն աշխատում է երկուսի համար: WAMP-ում համոզվեք, որ տեղադրեք laravel-ը «www» թղթապանակում և XAMPP-ում, ակնհայտորեն «htdocs»-ը:

ՔԱՅԼ-1) Բացեք «htdocs» թղթապանակը XAMPP-ում, պահեք SHIFT ստեղնը և աջ սեղմեք թղթապանակի վրա և ընտրեք «բաց հրամանի պատուհանը այստեղ»: Որպես այլընտրանք, դուք կարող եք բացել հրամանի պատուհանը և փոխել գրացուցակը «xampp/htdocs»:

ՔԱՅԼ-2) Մուտքագրեք հետևյալ հրամանը.

Կոմպոզիտոր ստեղծել-նախագիծ laravel/laravel my_laravel_site --prefer-dist

Այստեղ «my_laravel_site»-ը թղթապանակի անունն է, որտեղ տեղադրվելու են laravel ֆայլերը: Փոխեք սա ձեր ցանկությամբ:

ՔԱՅԼ-3) Այժմ ժամանակն է համբերատար լինել, քանի որ laravel-ի տեղադրումը որոշ ժամանակ կպահանջի:

ՔԱՅԼ-4) Տեղադրվելուց հետո հրամանի տողում փոխեք գրացուցակը «my_laravel_site» (cd «my_laravel_site») և մուտքագրեք ստորև նշված հրամանը:

Php արհեստավոր սպասարկում

ՔԱՅԼ-5) Սա ցույց կտա այնպիսի հաղորդագրություն, ինչպիսին է «Laravel-ի զարգացման սերվերը մեկնարկել է.» URL-ի հետ միասին:

ՔԱՅԼ-6) Պատճենեք և տեղադրեք url-ը բրաուզերի վրա: Եթե ​​ամեն ինչ ճիշտ է, դուք կտեսնեք laravel-ի ողջույնի էկրանը:

ՔԱՅԼ-7) Կատարված է: Դուք հաջողությամբ տեղադրել եք laravel-ը Windows-ի մեքենայի վրա և պատրաստ եք աշխատելու:

Դիմումի բանալի կարգավորում.

Laravel-ը տեղադրումից հետո քիչ կոնֆիգուրացիա է պահանջում: Այն պահանջում է, որ դուք սահմանեք հավելվածի բանալին: Սա 32 նիշից բաղկացած պատահական տող է, որն օգտագործվում է նստաշրջանի և այլ զգայուն տվյալների կոդավորման համար: Սովորաբար սա ավտոմատ կերպով կկարգավորվի, երբ դուք տեղադրեք laravel կոմպոզիտորի կամ laravel տեղադրողի միջոցով:

Եթե ​​այն կարգավորված չէ, դուք պետք է դա անեք ձեռքով: Նախ համոզվեք, որ ձեր հավելվածի արմատում «.env.example» ֆայլը վերանվանեք «.env»: Այնուհետև բացեք հրամանի տողը և փոխեք laravel նախագծի պանակը: Այժմ գործարկեք ստորև նշված հրամանը՝ բանալին ստեղծելու համար:

Php արհեստավոր բանալի:գեներացնել

Պատճենեք այս ստեղծված բանալին «.env» ֆայլի APP_KEY փոփոխականին: Խնայեք, և դուք պատրաստ եք:

Հատուկ Laravel տարբերակի տեղադրում.

Վերոնշյալ մեթոդը կոմպոզիտորին կստիպի ներբեռնել և տեղադրել laravel-ի վերջին տարբերակը: Եթե ​​ցանկանում եք ձեր մեքենայի վրա տեղադրել laravel-ի ավելի վաղ տարբերակները, համոզվեք, որ ստեղծեք-նախագիծ հրամանում ներառեք համապատասխան տարբերակի համարը:

Կոմպոզիտոր ստեղծել-նախագիծ laravel/laravel=5.4 your-project-name --prefer-dist Կարդացեք նաև.

Նույն կերպ դուք կարող եք հեշտությամբ տեղադրել laravel՝ օգտագործելով կոմպոզիտոր Windows-ի վրա. Հուսով եմ, որ այս ձեռնարկը օգտակար է ձեզ համար: Խնդրում ենք տարածել այն ձեր սոցիալական շրջանակում, եթե այն ձեզ դուր է գալիս:

Գրանցման համակարգի ստեղծման գործընթացը բավականին մեծ աշխատանք է։ Դուք պետք է գրեք կոդ, որը կրկնակի ստուգում է էլփոստի հասցեների վավերականությունը, ուղարկում է հաստատման էլ. Նույնիսկ այս ամենն անելիս օգտատերերը չեն ցանկանա գրանցվել, քանի որ նույնիսկ ամենանվազագույն գրանցումը պահանջում է նրանց ակտիվությունը:

Այսօրվա ձեռնարկում մենք կմշակենք գրանցման պարզ համակարգ, որը չի պահանջի որևէ գաղտնաբառ: Արդյունքները կլինեն համակարգ, որը կարող է հեշտությամբ փոփոխվել կամ ինտեգրվել գոյություն ունեցող PHP կայքէջում: Եթե ​​դուք հետաքրքրված եք, շարունակեք կարդալ:

PHP

Այժմ մենք պատրաստ ենք սկսել PHP կոդը: Գրանցման համակարգի հիմնական ֆունկցիոնալությունը տրամադրվում է User դասի կողմից, որը կարող եք տեսնել ստորև: Դասը օգտագործում է (), որը մինիմալիստական ​​տվյալների բազայի գրադարան է։ User դասը պատասխանատու է տվյալների բազա մուտք գործելու, մուտքի նշաններ ստեղծելու և դրանք վավերացնելու համար: Այն մեզ ներկայացնում է պարզ ինտերֆեյս, որը կարող է հեշտությամբ ներառվել ձեր PHP կայքերի գրանցման համակարգում:

User.class.php

// Մասնավոր ORM օրինակ
մասնավոր $orm;

/**
* Գտեք օգտվողին նշանային տողի միջոցով: Ընդունվում են միայն վավեր նշաններ
* նկատառում. Նշանն ուժի մեջ է ստեղծվելուց հետո 10 րոպեի ընթացքում:
* @param string $token Որոնվող նշանը
* @return Օգտագործող
*/

Հանրային ստատիկ ֆունկցիա findByToken($token)(

// գտեք այն տվյալների բազայում և համոզվեք, որ ժամանակի դրոշմը ճիշտ է


->where ("token", $token)
->where_raw ("token_validity > NOW()")
-> find_one();

Եթե ​​(!$result)(
վերադարձ կեղծ;
}

Վերադարձնել նոր օգտվող ($result);
}

/**
* Կամ մուտք գործեք կամ գրանցեք օգտվող:
* @return Օգտագործող
*/

Հանրային ստատիկ ֆունկցիա loginOrRegister($email)(

// Եթե նման օգտվող արդեն կա, վերադարձրեք այն

Եթե ​​(Օգտվող::առկա է ($email))(
վերադարձնել նոր օգտվող ($email);
}

// Հակառակ դեպքում ստեղծեք այն և վերադարձրեք այն

Վերադարձ օգտատեր::create($email);
}

/**
* Ստեղծեք նոր օգտվող և պահեք այն տվյալների բազայում
* @param string $email Օգտագործողի էլ.փոստի հասցեն
* @return Օգտագործող
*/

Մասնավոր ստատիկ ֆունկցիա ստեղծել ($email)(

// Գրեք նոր օգտվող տվյալների բազա և վերադարձրեք այն

$result = ORM::for_table ("reg_users")->create();
$result->email = $email;
$result->save();

Վերադարձնել նոր օգտվող ($result);
}

/**
* Ստուգեք, արդյոք այդպիսի օգտվող կա տվյալների բազայում և վերադարձրեք բուլյան:
* @param string $email Օգտագործողի էլ.փոստի հասցեն
* @return բուլյան
*/

Հանրային ստատիկ ֆունկցիան գոյություն ունի ($email)(

// Օգտագործողը կա՞ տվյալների բազայում:
$result = ORM::for_table («reg_users»)
->որտեղ ("email", $email)
->հաշվում ();

Վերադարձնել $result == 1;
}

/**
* Ստեղծեք օգտվողի նոր օբյեկտ
* @param $param ORM օրինակ, id, էլփոստ կամ null
* @return Օգտագործող
*/

Հանրային ֆունկցիա __կառուցում ($param = null)(

Եթե ​​(ORM-ի $param օրինակ)(

// Անցվել է ORM օրինակ
$this->orm = $param;
}
else if(is_string($param))(

// Նամակ է փոխանցվել
$this->
->where ("email", $param)
-> find_one();
}
ուրիշ (

If(is_numeric($param))(
// Օգտվողի ID-ն փոխանցվել է որպես պարամետր
$id = $param;
}
else if(isset($_SESSION["loginid"]))(

// Օգտվողի ID-ն չի փոխանցվել, նայեք նիստին
$id = $_SESSION["loginid"];
}

$this->orm = ORM::for_table("reg_users")
-> որտեղ ("id", $id)
-> find_one();
}

/**
* Ստեղծում է նոր SHA1 մուտքի նշան, այն գրում է տվյալների բազայում և վերադարձնում:
* @return տող
*/

Հանրային գործառույթը generateToken())(
// ստեղծել նշան մուտք գործած օգտվողի համար: Պահպանեք այն տվյալների բազայում:

$token = sha1($this->email.time().rand(0, 1000000));

// Պահպանեք նշանը տվյալների բազայում,
// և նշեք այն որպես վավեր միայն հաջորդ 10 րոպեների համար

$this->orm->set("token", $token);
$this->orm->set_expr("token_validity", "ADDTIME(NOW(),"0:10")");
$this->orm->save();

Վերադարձեք $token;
}

/**
*Մուտք գործեք այս օգտվողին
* @return void
*/

Հանրային գործառույթի մուտք ()

// Նշել օգտվողին որպես մուտք գործած
$_SESSION["loginid"] = $this->orm->id;

// Թարմացրեք last_login db դաշտը
$this->orm->set_expr("last_login", "NOW()");
$this->orm->save();
}

/**
* Ոչնչացնել նիստը և դուրս գալ օգտագործողից:
* @return void
*/

Հանրային ֆունկցիայի դուրս գալ ()
$_SESSION = զանգված();
unset ($_SESSION);
}

/**
* Ստուգեք, արդյոք օգտվողը մուտք է գործել:
* @return բուլյան
*/

Հանրային գործառույթը logedIn())(
վերադարձնել isset($this->orm->id) && $_SESSION["loginid"] == $this->orm->id;
}

/**
* Ստուգեք, արդյոք օգտվողը ադմինիստրատոր է
* @return բուլյան
*/

Հանրային գործառույթը Admin())(
return $this->rank() == "administrator";
}

/**
* Գտեք օգտագործողի տեսակը: Այն կարող է լինել կամ ադմինիստրատոր կամ սովորական:
* @return տող
*/

Հանրային ֆունկցիայի դասակարգում())(
if($this->orm->rank == 1)(
վերադարձ «ադմինիստրատոր»;
}

Վերադարձեք «սովորական»;
}

/**
* Կախարդական մեթոդ մասնավորի տարրեր մուտք գործելու համար
* $orm օրինակը որպես օգտագործողի օբյեկտի հատկություններ
* @param string $key Մուտք գործած գույքի անունը
* @return խառը
*/

Հանրային գործառույթ __get($key)(
if(isset($this->orm->$key))(
վերադարձնել $this->orm->$key;
}

Վերադարձնել զրոյական;
}
}
Նշանները ստեղծվում են ալգորիթմի միջոցով և պահվում տվյալների բազայում: Մենք օգտագործում ենք MySQL token_validity սյունակը 10 րոպե սահմանելու համար: Նշան վավերացնելիս մենք շարժիչին ասում ենք, որ մեզ անհրաժեշտ է նշան, token_validity դաշտը դեռ չի լրացել: Այս կերպ մենք սահմանափակում ենք այն ժամանակը, որի ընթացքում նշանը վավեր կլինի:

Ուշադրություն դարձրեք, որ մենք օգտագործում ենք __get() կախարդական մեթոդը փաստաթղթի վերջում՝ օգտվողի օբյեկտի հատկություններին մուտք գործելու համար: Սա մեզ թույլ է տալիս մուտք գործել տվյալների, որոնք պահվում են տվյալների բազայում որպես հատկություններ՝ $user->email, $user->token: Որպես օրինակ՝ տեսնենք, թե ինչպես կարող ենք օգտագործել այս դասը հետևյալ կոդի հատվածում.


Մեկ այլ ֆայլ, որը պահպանում է անհրաժեշտ ֆունկցիոնալությունը, functions.php-ն է։ Այնտեղ մենք ունենք մի քանի օգնական գործառույթներ, որոնք թույլ են տալիս մեզ ավելի կոկիկ պահել ծածկագրի մնացած մասը:

Functions.php

send_email ֆունկցիան ($from, $to, $subject, $message)(

// Օգնական ֆունկցիա էլփոստ ուղարկելու համար

$headers = "MIME-տարբերակ՝ 1.0" : «\r\n»;
$headers .= "Բովանդակության տեսակը. text/plain; charset=utf-8" . «\r\n»;
$headers .= "From: ".$from . «\r\n»;

Վերադարձ փոստ ($to, $subject, $message, $headers);
}

ֆունկցիա get_page_url())(

// Պարզեք PHP ֆայլի URL-ը

$url = "http".(դատարկ($_SERVER["HTTPS"])?"":"s"):"://".$_SERVER["SERVER_NAME"];

If(isset($_SERVER["REQUEST_URI"]) && $_SERVER["REQUEST_URI"] != "")(
$url.= $_SERVER["REQUEST_URI"];
}
ուրիշ (
$url.= $_SERVER["PATH_INFO"];
}

Վերադարձնել $url;
}

ֆունկցիայի արագություն_սահման ($ip, $limit_hour = 20, $limit_10_min = 10)(

// Այս IP հասցեի կողմից վերջին ժամվա ընթացքում մուտք գործելու փորձերի քանակը

$count_hour = ORM::for_table («reg_login_attempt»)
->
->where_raw("ts > SUBTIME(NOW(),"1:00")")
->հաշվում ();

// Այս IP հասցեի կողմից վերջին 10 րոպեի ընթացքում մուտք գործելու փորձերի քանակը

$count_10_min = ORM::for_table («reg_login_ttempt»)
->where("ip", sprintf("%u", ip2long($ip)))
->where_raw ("ts > SUBTIME(NOW(),"0:10")")
->հաշվում ();

If($count_hour > $limit_hour || $count_10_min > $limit_10_min)(
նետել նոր Բացառություն («Մուտքի շատ փորձեր»);
}
}

ֆունկցիա rate_limit_tick ($ip, $email)(

// Ստեղծեք նոր գրառում մուտքի փորձերի աղյուսակում

$login_attempt = ORM::for_table("reg_login_attempt")->create();

$login_attempt->email = $email;
$login_attempt->ip = sprintf("%u", ip2long($ip));

$login_attempt->save();
}

ֆունկցիայի վերահղում ($url)(
header («Գտնվելու վայրը՝ $url»);
ելք;
}
rate_limit և rate_limit_tick ֆունկցիաները թույլ են տալիս մեզ սահմանափակել թույլտվության փորձերի քանակը որոշակի ժամանակահատվածում: Թույլտվության փորձերը գրանցվում են reg_login_attempt տվյալների բազայում: Այս գործառույթները գործարկվում են, երբ մուտքի ձևը ստուգվում է, ինչպես կարող եք տեսնել հետևյալ կոդի հատվածում:

Ստորև բերված կոդը վերցված է index.php-ից և պատասխանատու է մուտքի ձևի վավերացման համար: Այն վերադարձնում է JSON պատասխան, որը պայմանավորված է jQuery կոդով, որը մենք տեսանք assets/js/script.js-ում:

index.php

Եթե ​​(! դատարկ ($_POST) && դրված է ($_SERVER["HTTP_X_REQUESTED_WITH"]))(

// Արտադրեք JSON վերնագիր

Վերնագիր («Բովանդակության տեսակ. հավելված/json»);

// Արդյո՞ք էլփոստի հասցեն վավեր է:

If(!isset($_POST["email"]) || !filter_var($_POST["email"], FILTER_VALIDATE_EMAIL))(
նետել նոր Բացառություն («Խնդրում ենք մուտքագրել վավեր էլ.
}

// Սա բացառություն կբերի, եթե մարդը վերևում է
// մուտքի փորձի թույլատրելի սահմանաչափերը (ավելին համար տե՛ս functions.php):
rate_limit ($_SERVER["REMOTE_ADDR"]);

// Գրանցեք այս մուտքի փորձը
rate_limit_tick ($_SERVER["REMOTE_ADDR"], $_POST["email"]);

// Ուղարկեք հաղորդագրությունը օգտվողին

$message = "";
$email = $_POST["email"];
$subject = «Ձեր մուտքի հղումը»;

Եթե(!Օգտվող::առկա է($email))(
$subject = "Շնորհակալություն գրանցվելու համար!";
$message = "Շնորհակալություն մեր կայքում գրանցվելու համար:\n\n";
}

// Փորձեք մուտք գործել կամ գրանցել անձին
$user = User::loginOrRegister($_POST["email"]);

$message.= "Դուք կարող եք մուտք գործել այս URL-ից.\n";
$message.= get_page_url()."?tkn=".$user->generateToken()."\n\n";

$message.= «Հղումը ինքնաբերաբար կսպառվի 10 րոպե անց»:;

$result = send_email($fromEmail, $_POST["email"], $subject, $message);

Եթե ​​(!$result)(
նետել նոր Բացառություն («Ձեր էլ. նամակն ուղարկելիս սխալ տեղի ունեցավ: Խնդրում ենք կրկին փորձել»:);
}

Die(json_encode(զանգված(
"message" => "Շնորհակալություն: Մենք հղում ենք ուղարկել ձեր մուտքի արկղին: Ստուգեք նաև ձեր սպամի թղթապանակը»:
)));
}
}
catch(Բացառություն $e)(

Die(json_encode(զանգված(
"error"=>1,
"message" => $e->getMessage()
)));
}
Հաջող թույլտվությունից կամ գրանցումից հետո վերոնշյալ կոդը նամակ է ուղարկում անձին՝ լիազորման համար հղումով: Տոկենը հասանելի է որպես $_GET փոփոխական «tkn»՝ գեներացված URL-ի պատճառով:

index.php

If(isset($_GET["tkn"]))(

// Սա վավեր մուտքի նշան է:
$user = User::findByToken($_GET["tkn"]);

// Այո՛ Մուտք գործեք օգտվողին և վերահղեք դեպի պաշտպանված էջ:

$user->login();
վերահղում ("protected.php");
}

// Անվավեր նշան: Վերահղում դեպի մուտքի ձև:
վերահղում ("index.php");
}
$user->login()-ի գործարկումը կստեղծի անհրաժեշտ նստաշրջանի փոփոխականները, որոնք թույլ կտան օգտվողին մնալ մուտք գործած հաջորդ մուտքերում:

Համակարգից դուրս գալն իրականացվում է մոտավորապես նույն կերպ.

Index.php

If(isset($_GET["logout"]))(

$user = նոր օգտվող();

Եթե ​​($user->loggedIn())(
$user->logout();
}

Վերահղում ("index.php");
}
Կոդի վերջում մենք օգտվողին կրկին ուղղորդում ենք դեպի index.php, այնպես որ URL-ում ?logout=1 պարամետրը վերացվում է:

Մեր index.php ֆայլը նույնպես պաշտպանության կարիք կունենա. մենք չենք ուզում, որ արդեն մուտք գործած օգտվողները տեսնեն ձևը: Դա անելու համար մենք օգտագործում ենք $user->loggedIn() մեթոդը՝

Index.php

$user = նոր օգտվող();

if($user->loggedIn())(
վերահղում ("protected.php");
}
Վերջապես, եկեք տեսնենք, թե ինչպես կարող եք պաշտպանել ձեր կայքի էջը և այն հասանելի դարձնել միայն լիազորումից հետո.

պաշտպանված.php

// Ձեր կայքի ցանկացած php էջ պաշտպանելու համար ներառեք main.php
// և ստեղծել նոր Օգտվողի օբյեկտ: Դա այնքան պարզ է:

require_once «ներառում է/main.php»;

$user = նոր օգտվող();

if(!$user->loggedIn())(
վերահղում ("index.php");
}
Այս ստուգումից հետո կարող եք վստահ լինել, որ օգտվողը հաջողությամբ մուտք է գործել: Դուք նաև մուտք կունենաք այն տվյալներին, որոնք պահվում են տվյալների բազայում որպես $user օբյեկտի հատկություններ: Օգտատիրոջ էլ.փոստը և նրա վարկանիշը ցուցադրելու համար օգտագործեք հետևյալ կոդը.

Echo «Ձեր էլ.փոստը՝ «.$user->email;
echo "Ձեր վարկանիշը. ".$user->rank();
Այստեղ rank()-ը մեթոդն է, քանի որ տվյալների բազայի դասակարգման սյունակը սովորաբար պարունակում է թվեր (0 սովորական օգտագործողների համար և 1՝ ադմինիստրատորների համար), և մենք պետք է այս ամենը փոխարկենք դասակարգման անունների, որն իրականացվում է այս մեթոդով։ Ստանդարտ օգտվողին ադմինիստրատորի փոխակերպելու համար պարզապես խմբագրեք օգտվողի մուտքը phpmyadmin-ում (կամ տվյալների բազայի ցանկացած այլ ծրագիր): Որպես ադմինիստրատոր՝ օգտատիրոջը որևէ հատուկ հնարավորություն չի տրվի: Դուք ինքներդ իրավունք ունեք ընտրելու, թե ինչ իրավունքներ տրամադրեք ադմինիստրատորներին:

Պատրաստ.

Դրանով մեր պարզ գրանցման համակարգը պատրաստ է: Դուք կարող եք օգտագործել այն գոյություն ունեցող PHP կայքում կամ արդիականացնել այն՝ ձեր սեփական պահանջներին համապատասխան:

Reg.ru՝ տիրույթներ և հոսթինգ

Ռուսաստանում ամենամեծ ռեգիստրատորը և հոսթինգ մատակարարը:

Ավելի քան 2 միլիոն դոմենային անուններ ծառայության մեջ:

Առաջխաղացում, տիրույթի փոստ, բիզնես լուծումներ:

Աշխարհի ավելի քան 700 հազար հաճախորդներ արդեն կատարել են իրենց ընտրությունը։

*Մկնիկը միացրեք՝ ոլորումը դադարեցնելու համար:

Հետ առաջ

PHP-ում և MySQL-ում օգտվողների գրանցման պարզ համակարգի ստեղծում

Գրանցման համակարգի ստեղծումը մեծ աշխատանք է: Դուք պետք է գրեք կոդ, որը վավերացնում է էլփոստի հասցեները, ուղարկում է գրանցումը հաստատող նամակ, ինչպես նաև վավերացնում է այլ ձևի դաշտերը և շատ ավելին:

Եվ նույնիսկ այս ամենը գրելուց հետո օգտատերերը չեն ցանկանա գրանցվել, քանի որ... սա նրանց կողմից որոշակի ջանք է պահանջում:

Այս ձեռնարկում մենք կստեղծենք գրանցման շատ պարզ համակարգ, որն ընդհանրապես չի պահանջում կամ չի պահում գաղտնաբառեր: Արդյունքը հեշտ կլինի փոփոխել և ավելացնել գոյություն ունեցող PHP կայքին: Ցանկանու՞մ եք պարզել, թե ինչպես է այն աշխատում: Կարդացեք ստորև.



Ահա թե ինչպես է աշխատելու մեր գերհասարակ համակարգը.

Մենք համատեղելու ենք թույլտվության ձևը և գրանցումը: Այս ձևը կունենա ձեր էլ.փոստի հասցեն մուտքագրելու դաշտ և գրանցման կոճակ;
- Էլփոստի հասցեով դաշտը լրացնելիս գրանցման կոճակի վրա սեղմելով կստեղծվի գրառում նոր օգտատիրոջ մասին, բայց միայն այն դեպքում, եթե մուտքագրված էլ. հասցեն չի գտնվել տվյալների բազայում:

Դրանից հետո ստեղծվում է նիշերի պատահական եզակի հավաքածու (token), որն ուղարկվում է օգտատիրոջ կողմից նշված էլ.
- Հղումը օգտվողին տանում է մեր կայք: Համակարգը որոշում է նշանի առկայությունը և լիազորում է օգտագործողին.

Այս մոտեցման առավելությունները.

Կարիք չկա պահպանել գաղտնաբառերը կամ վավերացնել դաշտերը.
- Կարիք չկա վերականգնել ձեր գաղտնաբառը, անվտանգության հարցերը և այլն;
- Օգտագործողի գրանցման/մուտքի պահից դուք միշտ կարող եք վստահ լինել, որ այս օգտվողը կլինի ձեր մուտքի գոտում (որ էլ. փոստի հասցեն ճիշտ է);
- Անհավատալիորեն պարզ գրանցման գործընթաց;

Թերություններ:

Օգտագործողի հաշվի անվտանգություն: Եթե ​​ինչ-որ մեկին հասանելի է օգտատիրոջ փոստը, նա կարող է մուտք գործել:
- Էլփոստն ապահով չէ և կարող է գաղտնալսվել: Հիշեք, որ այս հարցը տեղին է նաև այն դեպքում, երբ գաղտնաբառը մոռացվել է և անհրաժեշտ է վերականգնել, կամ ցանկացած թույլտվության համակարգում, որը չի օգտագործում HTTPS տվյալների փոխանցման համար (մուտք/գաղտնաբառ);
- Մինչ դուք ճիշտ կարգավորեք ձեր փոստի սերվերը, հավանականություն կա, որ թույլտվության հղումներով հաղորդագրությունները կհայտնվեն սպամում;

Համեմատելով մեր համակարգի առավելություններն ու թերությունները՝ կարելի է ասել, որ համակարգն ունի բարձր գործածականություն (առավելագույն հարմարավետություն վերջնական օգտագործողի համար) և, միևնույն ժամանակ, ունի անվտանգության ցածր ցուցանիշ։

Այսպիսով, առաջարկվում է օգտագործել այն ֆորումներում և ծառայություններում գրանցումների համար, որոնք չեն աշխատում կարևոր տեղեկատվության հետ:

Ինչպես օգտագործել այս համակարգը

Եթե ​​դուք պարզապես պետք է օգտագործեք համակարգ՝ ձեր կայքում օգտատերերին թույլատրելու համար, և չեք ցանկանում այս դասը կտոր-կտոր անել, ահա թե ինչ պետք է անեք.

Դուք պետք է ներբեռնեք դասին կից աղբյուրները
- Գտեք tables.sql ֆայլը արխիվում: Ներմուծեք այն ձեր տվյալների բազա՝ օգտագործելով phpMyAdmin-ի ներմուծման տարբերակը: Այլընտրանք. բացեք այս ֆայլը տեքստային խմբագրիչի միջոցով, պատճենեք SQL հարցումը և կատարեք այն;
- Բացեք include/main.php-ը և լրացրեք ձեր տվյալների բազայի հետ միանալու կարգավորումները (նշեք տվյալների բազայի հետ միանալու օգտվողին և գաղտնաբառը, ինչպես նաև տվյալների բազայի հոսթն ու անվանումը): Նույն ֆայլում պետք է նշեք նաև էլ. փոստը, որը կօգտագործվի որպես համակարգի կողմից ուղարկված հաղորդագրությունների սկզբնական հասցե: Որոշ հյուրընկալողներ արգելափակում են ելքային էլ.
- Վերբեռնեք բոլոր index.php, protected.php ֆայլերը և ակտիվները և ներառում թղթապանակներ FTP-ի միջոցով ձեր հոսթին;
- Ստորև բերված կոդը ավելացրեք յուրաքանչյուր PHP էջի վրա, որտեղ ցանկանում եք ցուցադրել մուտքի ձևը;

Require_once «ներառում է/main.php»; $user = նոր օգտվող(); if(!$user->loggedIn())(վերահղում("index.php");)
-Պատրա՞ստ:

Նրանց համար, ովքեր հետաքրքրված են, թե ինչպես է այդ ամենը աշխատում, կարդացեք ստորև:

Առաջին քայլը թույլտվության ձևի համար HTM կոդը գրելն է: Այս կոդը գտնվում է index.php ֆայլում։ Այս ֆայլը պարունակում է նաև PHP կոդ, որը մշակում է ձևի տվյալները և մուտքի համակարգի այլ օգտակար գործառույթներ: Դուք կարող եք ավելին իմանալ այս մասին ստորև բերված բաժնում, որը նվիրված է PHP կոդի վերանայմանը:

index.php

Ձեռնարկ. Գերազանց պարզ գրանցման համակարգ PHP և MySQL Մուտք գործելու կամ գրանցելու միջոցով

Մուտքագրեք ձեր էլ. հասցեն վերևում և մենք կուղարկենք
դուք մուտքի հղում եք:

Մուտք/գրանցում

Գլխի բաժնում (և պիտակների միջև) ես ներառել եմ հիմնական ոճերը (դրանք ներառված չեն այս ձեռնարկում, այնպես որ կարող եք ինքներդ դիտել դրանք: Թղթապանակ assets/css/style.css): Նախքան փակման պիտակը, ես ներառեցի jQuery գրադարանը և script.js ֆայլը, որը մենք կգրենք և կվերլուծենք ստորև։


JavaScript

jQuery-ն հետևում է «Գրանցվել/Մուտք» կոճակի վիճակին՝ օգտագործելով գործառույթը e.preventDefault()և ուղարկում է AJAX հարցումներ: Կախված սերվերի պատասխանից, այն ցուցադրում է այս կամ այն ​​հաղորդագրությունը և որոշում հետագա գործողությունները/

assets/js/script.js

$(function())( var form = $("#login-register"); form.on("submit", function(e)( if(form.is(".loading, .loggedIn"))(վերադարձ false ;) var էլ. ֆունկցիա (m)( if(m.error)( form.addClass("սխալ"); messageHolder.text(m.message); ) else(form.removeClass("error").addClass("loggedIn"); messageHolder տեքստ (m.հաղորդագրություն); ) )); )); $(փաստաթուղթ).ajaxStart(function()) (form.addClass(«բեռնում»); )); $(փաստաթուղթ).ajaxComplete(function()) ( ձև. removeClass («բեռնում»); )); ));

Ավելացվել է ձևին՝ AJAX հարցման ներկա վիճակը ցուցադրելու համար (դա հնարավոր է դարձել մեթոդների շնորհիվ ajaxStart ()) Եվ ajaxComplete (), որը կարող եք գտնել ֆայլի վերջում):

Այս դասը ցուցադրում է պտտվող անիմացիոն GIF ֆայլ (կարծես ակնարկում է մեզ, որ հարցումը մշակվում է), ինչպես նաև գործում է որպես դրոշակ՝ կանխելու ձևի նորից ներկայացումը (երբ գրանցման կոճակն արդեն մեկ անգամ սեղմված է): .loggedIn դասը ևս մեկ դրոշ է. այն սահմանվում է, երբ էլփոստն ուղարկվում է: Այս դրոշը անմիջապես արգելափակում է ձևի հետ կապված ցանկացած հետագա գործողություն:

Տվյալների բազայի սխեման

Մեր աներևակայելի պարզ գրանցման համակարգը օգտագործում է 2 MySQL աղյուսակ (SQL կոդը գտնվում է tables.sql ֆայլում): Առաջինը պահպանում է օգտատերերի հաշիվների մասին տվյալները: Երկրորդը պահում է տեղեկատվություն մուտք գործելու փորձերի քանակի մասին:


Օգտագործողի աղյուսակի սխեման.

Համակարգը չի օգտագործում գաղտնաբառեր, ինչպես երևում է դիագրամում: Դրա վրա կարող եք տեսնել token-ի սյունակը token_validity սյունակին կից նշաններով: Թոքենը տեղադրվում է հենց որ օգտատերը միանում է համակարգին և սահմանում է իր էլ. Token_validity սյունակը սահմանում է ժամանակը 10 րոպե անց, որից հետո նշանն այլևս վավեր չէ:


Աղյուսակի սխեման, որը հաշվում է թույլտվության փորձերի քանակը:

Երկու աղյուսակներում էլ IP հասցեն պահվում է մշակված ձևով՝ օգտագործելով ip2long ֆունկցիան ամբողջ թվի տիպի դաշտում։

Այժմ մենք կարող ենք գրել որոշ PHP կոդ: Համակարգի հիմնական ֆունկցիոնալությունը վերագրված է User.class.php դասին, որը կարող եք տեսնել ստորև։

Այս դասը ակտիվորեն օգտագործում է idorm (docs), այս գրադարանները նվազագույն անհրաժեշտ գործիքներն են տվյալների բազաների հետ աշխատելու համար։ Այն կարգավորում է տվյալների բազայի հասանելիությունը, նշանների ստեղծումը և նշանի վավերացումը: Այն ապահովում է պարզ ինտերֆեյս, որը հեշտացնում է գրանցման համակարգը ձեր կայքին միացնելը, եթե այն օգտագործում է PHP:

User.class.php

Class User( // Private ORM case private $orm; /** * Գտեք օգտվողին ըստ նշանի: Միայն վավեր նշաններն ընդունվում են քննարկման համար: Նշանը ստեղծվում է միայն 10 րոպեի ընթացքում այն ​​ստեղծման պահից * @param string $token Սա այն մեկն է, որը մենք փնտրում ենք նշան * @return Օգտվող Վերադարձրեք Օգտագործողի ֆունկցիայի արժեքը */ հանրային ստատիկ ֆունկցիան findByToken($token)( // գտեք նշանը տվյալների բազայում և համոզվեք, որ ճիշտ ժամանակի դրոշմը դրված է $result = ORM::for_table ("reg_users") ->որտեղ ("token", $token) ->where_raw ("token_validity > NOW()") ->find_one(); if(!$result)( return false; ) վերադարձնել նոր օգտատեր($result); ) /** * Թույլատրել կամ գրանցել օգտվողին * @param string $email Օգտվողի էլփոստի հասցեն * @return Օգտվողի */ հանրային ստատիկ ֆունկցիայի loginOrRegister($email)( // Եթե այդպիսի օգտվող արդեն գոյություն ունի, վերադարձրեք Օգտվողի ֆունկցիայի արժեքը տվյալների բազայում պահվող նշված էլ.փոստի հասցեից if(User::exists($email))( return new User($email); ) // Հակառակ դեպքում ստեղծեք նոր օգտվող տվյալների բազայում և վերադարձնել User::create ֆունկցիայի արժեքը նշված էլ.փոստից return User::create($email ); ) /** * Ստեղծեք նոր օգտվող և պահեք տվյալների բազայում * @param string $email: Օգտագործողի էլ.փոստի հասցեն * @return Օգտվողի */ մասնավոր ստատիկ ֆունկցիա ստեղծել ($email)( // Գրեք նոր օգտվող և վերադարձրեք Օգտվողի ֆունկցիայի արդյունքը այս արժեքներից $result = ORM::for_table("reg_users")- >create(); $result->email = $email; $result->save(); վերադարձնել նոր օգտվող ($result); ) /** * Ստուգեք, արդյոք այդպիսի օգտվող կա տվյալների բազայում և վերադարձրեք բուլյան արժեքը: փոփոխականը * @param string $email. Օգտատիրոջ էլփոստի հասցեն * @return բուլյան */ հանրային ստատիկ ֆունկցիան գոյություն ունի ($email)( // Օգտագործողը կա՞ տվյալների բազայում: $result = ORM::for_table("reg_users") ->where("email", $email ) ->count(); return $result == 1;) /** * Ստեղծել նոր օգտվողի օբյեկտ * @param օրինակ $param ORM, id, էլ. null) ( if($param instanceof ORM)( // ORM ստուգումն անցել է $this->orm = $param; ) else if(is_string($param))( // Էլփոստի ստուգումն անցել է $this->orm = ORM:: for_table ("reg_users") ->where("email", $param) ->find_one(); ) else($id = 0; if(is_numeric($param))( // $param փոփոխականի արժեքը է. փոխանցվել է օգտվողի նույնացուցիչին $id = $param; ) else if(isset($_SESSION["loginid"]))( // Հակառակ դեպքում տես նիստը $id = $_SESSION["loginid"]; ) $this->orm = ORM::for_table( "reg_users") ->where("id", $id) ->find_one(); ) ) /** * Ստեղծեք նոր SHA1 թույլտվության նշան, գրում այն ​​տվյալների բազայում և վերադարձնում դրա արժեքը * @return string */ public function generateToken( )( // Ստեղծեք նշան լիազորված օգտվողի համար և պահեք այն $token = sha1($this->email.time().rand(0, 1000000)); // Պահպանեք նշանը տվյալների բազայում // Եվ նշեք այն որպես վավեր միայն հաջորդ 10 րոպեների համար $this->orm->set("token", $token); $this->orm->set_expr("token_validity", "ADDTIME(NOW(),"0:10")"); $this->orm->save(); վերադարձնել $ նշան; ) /** * Թույլատրել օգտվողին * @return void */ public ֆունկցիա login())( // Նշել օգտվողին որպես մուտքագրված $_SESSION["loginid"] = $this->orm->id; // Թարմացնել last_login տվյալների բազայի դաշտի արժեքը $this->orm->set_expr("last_login", "NOW()"); * @return void */ հանրային ֆունկցիայի դուրս գալ ()( $_SESSION = array(); unset($_SESSION); ) /** * Ստուգեք, արդյոք օգտվողը մուտք է գործել * @return բուլյան */ հանրային ֆունկցիա logedIn())( return isset($this->orm->id) && $_SESSION["loginid"] == $this->orm->id; ) /** * Ստուգում է արդյոք օգտվողը ադմինիստրատոր է * @return բուլյան */ public ֆունկցիա isAdmin())( return $this->rank() = = "administrator"; ) /** * Գտեք օգտվողի տեսակը, կարող է լինել կամ ադմինիստրատոր կամ սովորական * @return string */ public function rank())(եթե ($this->orm->rank == 1)( return "administrator" "; ) return "regular"; ) /** * Մեթոդ, որը թույլ է տալիս ստանալ օգտվողի անձնական տեղեկությունները որպես * Օգտատիրոջ օբյեկտի * հատկություններ * @ param string $key Անվանումը սեփականության, որը ստանում է մուտք * @return խառը */ հանրային ֆունկցիա __get($key)( if(isset($this->orm->$key))( return $this->orm-> $ բանալի; ) վերադարձնել զրոյական; ))

Նշանները ստեղծվում են SHA1 ալգորիթմի միջոցով և պահվում տվյալների բազայում: Ես օգտագործում եմ MySQL-ի ժամանակային գործառույթները՝ նշանի վավերականության համար 10 րոպեանոց ժամկետ սահմանելու համար:

Երբ նշանը վավերացվում է, մենք ուղղակիորեն ասում ենք մշակողին, որ մենք դիտարկում ենք միայն այն նշանները, որոնք դեռ ժամկետանց չեն և պահվում են token_validity սյունակում:

Խնդրում ենք նկատի ունենալ, որ ես օգտագործում եմ կախարդական մեթոդը __ստանալ docs գրադարանը ֆայլի վերջում՝ օգտագործողի օբյեկտի հատկություններին հասանելիությունը կասեցնելու համար:

Դրա շնորհիվ տվյալների բազայում պահվող տեղեկատվության հասանելիությունը հնարավոր է դառնում $user->email, $user->token և այլն հատկությունների շնորհիվ: Կոդի հաջորդ հատվածում մենք կանդրադառնանք, թե ինչպես օգտագործել այս դասերը որպես օրինակ: .


Պաշտպանված էջ

Մեկ այլ ֆայլ, որը պահպանում է օգտակար և անհրաժեշտ գործառույթները, functions.php ֆայլն է։ Կան մի քանի այսպես կոչված օգնականներ՝ օգնական գործառույթներ, որոնք թույլ են տալիս ստեղծել ավելի մաքուր և ընթեռնելի կոդ այլ ֆայլերում:

functions.php

send_email ($from, $to, $subject, $message) ֆունկցիա ( // Օգնող, որը նամակ է ուղարկում $headers = "MIME-տարբերակ՝ 1.0" . "\r\n"; $headers .= "Բովանդակության տեսակը. տեքստ /plain; charset=utf-8" . "\r\n"; $headers .= "From: ".$from . "\r\n"; վերադարձ փոստ ($to, $subject, $message, $headers ); ) ֆունկցիա get_page_url())( // Որոշեք PHP ֆայլի URL-ը $url = "http".(դատարկ($_SERVER["HTTPS"])?"":"s")."://" .$_SERVER ["SERVER_NAME"]; if(isset($_SERVER["REQUEST_URI"]) && $_SERVER["REQUEST_URI"] != "")($url.= $_SERVER["REQUEST_URI"]; ) else( $url. = $_SERVER["PATH_INFO"]; ) վերադարձնել $url; ) ֆունկցիա rate_limit($ip, $limit_hour = 20, $limit_10_min = 10)( // Վերջին ժամում այս IP հասցե մուտք գործելու փորձերի քանակը $ count_hour = ORM: :for_table("reg_login_attempt") ->where("ip", sprintf("%u", ip2long($ip))) ->where_raw("ts > SUBTIME(NOW(),"1:00 ")") ->count(); // Մուտք գործելու փորձերի քանակը վերջին 10 րոպեի ընթացքում այս IP հասցեում $count_10_min = ORM::for_table("reg_login_attempt") ->where("ip", sprintf("%u ", ip2long($ ip))) ->where_raw("ts > SUBTIME(NOW(),"0:10")") ->count(); if($count_hour > $limit_hour || $count_10_min > $limit_10_min)( throw new Exception(«Չափից շատ մուտք գործելու փորձեր»); ) ) ֆունկցիա rate_limit_tick($ip, $email)( // Ստեղծել նոր գրառում աղյուսակում որը հաշվում է մուտքի փորձերի քանակը $login_attempt = ORM::for_table("reg_login_attempt")->create();$login_attempt->email = $email; $login_attempt->ip = sprintf("%u", ip2long($ip )); $login_attempt->save(); ) ֆունկցիայի վերահղում($url)( header(«Գտնվելու վայրը. $url»); ելք;)

Գործառույթներ տոկոսադրույքի_սահմանԵվ rate_limit_tickվերահսկել թույլտվության փորձերի քանակը առաջին փորձից հետո անցած ժամանակահատվածում: Մուտքի փորձը գրանցվում է տվյալների բազայում reg_login_attempt սյունակում: Այս գործառույթները կանչվում են, երբ ձևի տվյալները մշակվում և ներկայացվում են, ինչպես կարող եք տեսնել հետևյալ կոդի հատվածից:

Ստորև բերված կոդը վերցված է index.php ֆայլից և այն մշակում է ձևի ներկայացումը: Այն վերադարձնում է JSON պատասխան, որն իր հերթին մշակվում է jQuery-ի կողմից assets/js/script.js ֆայլում, որը մենք ավելի վաղ դիտել ենք:

index.php

Փորձեք( if(!empty($_POST) && isset($_SERVER["HTTP_X_REQUESTED_WITH"]))( // Արտադրեք JSON վերնագիր ("Content-type: application/json"); // Արդյո՞ք այս էլփոստի հասցեն վավեր է, եթե (!isset($_POST["էլ.փոստ"]) || !filter_var($_POST["էլ.փոստ"], FILTER_VALIDATE_EMAIL)) (նոր Բացառություն ("Խնդրում եմ մուտքագրեք վավեր էլ. նամակ"); ) // Ստուգեք: օգտվողին թույլատրված է մուտք գործել, արդյոք նա գերազանցե՞լ է թույլատրված կապերի քանակը: (functions.php ֆայլ լրացուցիչ տեղեկությունների համար) rate_limit($_SERVER["REMOTE_ADDR"]); // Մուտք գործեք այս մուտքի փորձ rate_limit_tick($_SERVER["REMOTE_ADDR"] , $ _POST["email"]); // Նամակ ուղարկեք օգտվողին $message = ""; $email = $_POST["email"]; $subject = "Ձեր մուտքի հղումը"; if(!Օգտվող:: exists($email) )( $subject = "Շնորհակալություն գրանցվելու համար!"; $message = "Շնորհակալություն մեր կայքում գրանցվելու համար:\n\n"; ) // Փորձեք թույլատրել կամ գրանցել օգտվողին $user = Օգտագործող ::loginOrRegister($_POST[ "email"]);$message.= "Դուք կարող եք մուտք գործել այս URL-ից:\n"; $message.= get_page_url()."?tkn=".$user->generateToken()."\n\n"; $message.= «Հղումը ինքնաբերաբար կսպառվի 10 րոպե անց»:; $result = send_email($fromEmail, $_POST["email"], $subject, $message); if(!$result)( throw new Exception("Ձեր էլ. նամակն ուղարկելիս սխալ է տեղի ունեցել: Խնդրում ենք կրկին փորձել"); ) die(json_encode(array("message" => "Շնորհակալություն: Մենք հղում ենք ուղարկել դեպի ձեր մուտքի արկղ: Ստուգեք նաև ձեր սպամի թղթապանակը։"))); ) ) catch(Exception $e)( die(json_encode(array("error"=>1, "message" => $e->getMessage() )))))

Հաջող մուտքից/գրանցումից հետո վերը նշված կոդը օգտվողին կուղարկի մուտքի հղում: Նշանը հասանելի է դառնում, քանի որ այն փոխանցվում է որպես փոփոխական գեներացված հղումում մեթոդով $_GET tkn մարկերով

index.php

If(isset($_GET["tkn"]))( // Արդյո՞ք այս նշանը վավեր է լիազորման համար: $user = User::findByToken($_GET["tkn"]); if($user)( // Այո, է. Վերահղում դեպի պաշտպանված էջ $user->login(); redirect("protected.php"); ) // Ոչ, նշանը վավեր չէ: Վերահղում դեպի թույլտվություն/գրանցման ձև redirect("index. php ");)

$user->login()

կստեղծի նիստի համար անհրաժեշտ փոփոխականները, որպեսզի օգտվողը, դիտելով կայքի հետագա էջերը, միշտ լիազորված մնա:

Համակարգից դուրս գալու գործառույթի մշակումը կազմակերպվում է նույն կերպ:

index.php

If(isset($_GET["logout"]))($user = new User(); if($user->loggedIn())($user->logout(); ) redirect ("index.php") ;)

Կոդի վերջում ես կրկին վերահղում եմ սահմանել index.php-ին, ուստի պարամետրը ?ելք=1 URL-ով փոխանցելը պարտադիր չէ:

Մեր index.php ֆայլը լրացուցիչ պահանջում է: պաշտպանություն. մենք չենք ցանկանում, որ մարդիկ, ովքեր մուտք են գործել համակարգ, նորից տեսնեն գրանցման ձևը: Այս նպատակների համար մենք օգտագործում ենք մեթոդը $user->loggedIn().

index.php

$user = նոր օգտվող(); if($user->loggedIn())(վերահղում("protected.php");)

Վերջապես, ահա մի կոդ, որը թույլ է տալիս պաշտպանել ձեր կայքի էջերը և այն հասանելի դարձնել միայն թույլտվությունից հետո:

պաշտպանված.php

// Ձեր կայքի յուրաքանչյուր էջը պաշտպանելու համար ներառեք main.php ֆայլ // և ստեղծեք նոր Օգտվողի օբյեկտ: Ահա թե որքան հեշտ է դա: require_once «ներառում է/main.php»; $user = նոր օգտվող(); if(!$user->loggedIn())(վերահղում("index.php"); )

Այս ստուգումից հետո կարող եք վստահ լինել, որ օգտատերը հաջողությամբ լիազորված է: Դուք կարող եք նաև մուտք գործել տվյալների բազայում պահված տեղեկություններ՝ օգտագործելով օբյեկտի հատկությունները $user. Օգտատիրոջ էլ.փոստը և կարգավիճակը ցուցադրելու համար օգտագործեք այս կոդը.

Echo «Ձեր էլ.փոստը՝ «.$user->email; echo "Ձեր վարկանիշը. ".$user->rank();

Մեթոդ աստիճան()օգտագործվում է այստեղ, քանի որ տվյալների բազան սովորաբար պահում է թվեր (0 սովորական օգտագործողի համար, 1՝ ադմինիստրատորի համար), և մենք պետք է այս տվյալները փոխարկենք այն կարգավիճակներին, որոնց պատկանում են, ինչում մեզ օգնում է այս մեթոդը։

Սովորական օգտվողին ադմինիստրատոր դարձնելու համար պարզապես խմբագրեք օգտվողի մուտքը phpMyAdmin-ի միջոցով (կամ որևէ այլ ծրագրի, որը թույլ է տալիս կառավարել տվյալների բազաները): Ադմինիստրատորի կարգավիճակը որևէ արտոնություն չի տալիս, այս օրինակում էջը կցուցադրի, որ դուք ադմինիստրատոր եք, և վերջ:

Բայց ինչ անել սրա հետ, թողնված է ձեր հայեցողությանը. դուք կարող եք ինքներդ գրել և կազմել կոդ, որը սահմանում է որոշակի արտոնություններ և հնարավորություններ ադմինիստրատորների համար:

Մենք ավարտեցինք:

Մենք վերջացրել ենք այս անհավանական սուպեր քվազի պարզ ձևը: Դուք կարող եք այն օգտագործել ձեր PHP կայքերում, դա բավականին պարզ է: Դուք կարող եք նաև փոփոխել այն ինքներդ ձեզ և դարձնել այն այնպես, ինչպես ցանկանում եք:

Նյութը պատրաստել է Դենիս Մալիշոկը հատուկ կայքի համար

P.S. Ցանկանու՞մ եք առաջ շարժվել PHP-ի և OOP-ի յուրացման գործում: Ուշադրություն դարձրեք կայքի կառուցման տարբեր ասպեկտների պրեմիում դասերին, ներառյալ PHP-ում ծրագրավորումը, ինչպես նաև PHP-ում ձեր սեփական CMS համակարգը զրոյից OOP-ով ստեղծելու անվճար դասընթացին:

Ձեզ դուր եկավ նյութը և ցանկանում եք շնորհակալություն հայտնել ինձ:
Պարզապես կիսվեք ձեր ընկերների և գործընկերների հետ:




Նորություն կայքում

>

Ամենահայտնի