ReactJS
Users
Вход через Facebook в React с использованием Parse и React
10 мин
вход через facebook в react введение в последних уроках вы создали функцию входа/выхода пользователя в ваше приложение, используя класс parse user parse user теперь вы узнаете, как использовать вход через facebook для получения данных пользователя из facebook и входа, регистрации или связывания существующих пользователей с ним вы также установите и настроите библиотеку react facebook login react facebook login для достижения этой цели метод parse user linkwith parse user linkwith отвечает за регистрацию и вход пользователей, используя любой метод аутентификации третьих сторон, при условии, что вы передаете правильные параметры, запрашиваемые каждым различным провайдером после связывания данных пользователя с новым или существующим parse user parse user , parse сохранит действительную сессию пользователя на вашем устройстве будущие вызовы методов, таких как current current , успешно извлекут ваши данные пользователя, так же как и при обычных входах предварительные требования чтобы завершить этот учебник, вам потребуется созданное приложение react и https //www back4app com/docs/react/quickstart завершите предыдущий гид, чтобы лучше понять https //www back4app com/docs/react/working with users/react user login если вы хотите протестировать/использовать макет экрана, предоставленный этим руководством, вам следует настроить https //ant design/docs/react/introduce цель создать функцию входа пользователя с использованием facebook login на parse для приложения react 1 установка зависимостей самый популярный способ включить facebook login в react использовать react facebook login react facebook login для его обработки настройте его, следуя https //github com/keppelen/react facebook login/ чтобы использовать компонент lib, вам нужно указать действительный идентификатор приложения facebook appid appid , поэтому создайте его на своей панели разработчика facebook, следуя одному из их https //developers facebook com/docs/development/create an app/ после этого добавьте возможность входа через facebook в ваше приложение, выбрав опцию www, указав https //localhost 3000 https //localhost 3000 в качестве url вашего сайта вход через facebook требует, чтобы ваше соединение было безопасным, даже при входе в среду разработки поэтому вам нужно настроить доступ по https для вашего react приложения, создав локальный сертификат, предоставив ему полные разрешения в вашей ос и добавив файлы в ваш проект поскольку каждая ос может иметь свои особенности, это не будет рассмотрено в руководстве после создания сертификата убедитесь, что вы изменили в скриптах скриптах сессии вашего package json package json файла команду запуска на 1 "start" "export https=true&\&ssl crt file=cert pem&\&ssl key file=key pem react scripts start", если вы используете typescript, вам нужно создать новый файл в вашей src src папке с названием react facebook login d ts react facebook login d ts содержащий react facebook login react facebook login декларацию модуля для использования версии компонента без стилей react facebook login d ts 1 declare module 'react facebook login/dist/facebook login render props'; 2 использование facebook login с parse теперь давайте создадим новый метод внутри userlogin userlogin компонента, который будет обрабатывать ответ при вызове модального окна аутентификации facebook login если пользователь войдет через facebook, этот вызов получит данные пользователя из facebook, и вам нужно будет сохранить id id , accesstoken accesstoken , и профиль email email затем функция попытается войти в систему на parse, используя метод parse user linkwith parse user linkwith и эти учетные данные обратите внимание, что если ваш пользователь уже зарегистрировался с помощью этой аутентификации facebook, linkwith linkwith войдёт в систему, используя существующую учетную запись javascript 1 const handlefacebookloginloginresponse = async function(response) { 2 // check if response has an error 3 if (response error !== undefined) { 4 console log(`error ${response error}`); 5 return false; 6 } else { 7 try { 8 // gather facebook user info 9 const userid = response id; 10 const useremail = response email; 11 const useraccesstoken = response accesstoken; 12 // try to login on parse using linkwith and these credentials 13 // create a new parse user object 14 const usertologin = new parse user(); 15 // set username and email to match facebook profile email 16 usertologin set('username', useremail); 17 usertologin set('email', useremail); 18 try { 19 let loggedinuser = await usertologin 20 linkwith('facebook', { 21 authdata {id userid, access token useraccesstoken}, 22 }); 23 // login returns the corresponding parseuser object 24 alert( 25 `success! user ${loggedinuser get('username')} has successfully signed in!`, 26 ); 27 // update state variable holding current user 28 getcurrentuser(); 29 return true; 30 } catch (error) { 31 // error can be caused by wrong parameters or lack of internet connection 32 alert(`error! ${error message}`); 33 return false; 34 } 35 } catch (error) { 36 console log("error gathering facebook user info, please try again!") 37 return false; 38 } 39 } 40 }1 const handlefacebookloginloginresponse = async function(response any) promise\<boolean> { 2 // check if response has an error 3 if (response error !== undefined) { 4 console log(`error ${response error}`); 5 return false; 6 } else { 7 try { 8 // gather facebook user info 9 const userid string = response id; 10 const useremail string = response email; 11 const useraccesstoken string = response accesstoken; 12 // try to login on parse using linkwith and these credentials 13 // create a new parse user object 14 const usertologin parse user = new parse user(); 15 // set username and email to match facebook profile email 16 usertologin set('username', useremail); 17 usertologin set('email', useremail); 18 try { 19 let loggedinuser parse user = await usertologin 20 linkwith('facebook', { 21 authdata {id userid, access token useraccesstoken}, 22 }); 23 // login returns the corresponding parseuser object 24 alert( 25 `success! user ${loggedinuser get('username')} has successfully signed in!`, 26 ); 27 // update state variable holding current user 28 getcurrentuser(); 29 return true; 30 } catch (error any) { 31 // error can be caused by wrong parameters or lack of internet connection 32 alert(`error! ${error message}`); 33 return false; 34 } 35 } catch (error any) { 36 console log("error gathering facebook user info, please try again!") 37 return false; 38 } 39 } 40 } после этого вам нужно использовать react facebook login react facebook login facebooklogin facebooklogin компонент, чтобы вызвать модальное окно входа в facebook, добавив его в ваш jsx код вы можете использовать стандартный стиль facebook или создать свой собственный, что является подходом, описанным в этом руководстве вот полный код компонента userlogin userlogin компонента, обратите внимание на react facebook login react facebook login кнопку и то, как она связана с методом ответа модального окна, созданным ранее javascript 1 import react, { usestate } from 'react'; 2 import parse from 'parse/dist/parse min js'; 3 import facebooklogin from 'react facebook login/dist/facebook login render props'; 4 import ' /app css'; 5 import { button, divider, input } from 'antd'; 6	 7 export const userlogin = () => { 8 // state variables 9 const \[username, setusername] = usestate(''); 10 const \[password, setpassword] = usestate(''); 11 const \[currentuser, setcurrentuser] = usestate(null); 12	 13 const douserlogin = async function () { 14 // note that these values come from state variables that we've declared before 15 const usernamevalue = username; 16 const passwordvalue = password; 17 try { 18 const loggedinuser = await parse user login(usernamevalue, passwordvalue); 19 // login returns the corresponding parseuser object 20 alert( 21 `success! user ${loggedinuser get( 22 'username' 23 )} has successfully signed in!` 24 ); 25 // to verify that this is in fact the current user, `current` can be used 26 const currentuser = await parse user current(); 27 console log(loggedinuser === currentuser); 28 // clear input fields 29 setusername(''); 30 setpassword(''); 31 // update state variable holding current user 32 getcurrentuser(); 33 return true; 34 } catch (error) { 35 // error can be caused by wrong parameters or lack of internet connection 36 alert(`error! ${error message}`); 37 return false; 38 } 39 }; 40	 41 const douserlogout = async function () { 42 try { 43 await parse user logout(); 44 // to verify that current user is now empty, currentasync can be used 45 const currentuser = await parse user current(); 46 if (currentuser === null) { 47 alert('success! no user is logged in anymore!'); 48 } 49 // update state variable holding current user 50 getcurrentuser(); 51 return true; 52 } catch (error) { 53 alert(`error! ${error message}`); 54 return false; 55 } 56 }; 57	 58 // function that will return current user and also update current username 59 const getcurrentuser = async function () { 60 const currentuser = await parse user current(); 61 // update state variable holding current user 62 setcurrentuser(currentuser); 63 return currentuser; 64 }; 65	 66 const handlefacebookloginloginresponse = async function (response) { 67 // check if response has an error 68 if (response error !== undefined) { 69 console log(`error ${response error}`); 70 return false; 71 } else { 72 try { 73 // gather facebook user info 74 const userid = response id; 75 const useremail = response email; 76 const useraccesstoken = response accesstoken; 77 // try to login on parse using linkwith and these credentials 78 // create a new parse user object 79 const usertologin = new parse user(); 80 // set username and email to match facebook profile email 81 usertologin set('username', useremail); 82 usertologin set('email', useremail); 83 try { 84 let loggedinuser = await usertologin linkwith('facebook', { 85 authdata { id userid, access token useraccesstoken }, 86 }); 87 // login returns the corresponding parseuser object 88 alert( 89 `success! user ${loggedinuser get( 90 'username' 91 )} has successfully signed in!` 92 ); 93 // update state variable holding current user 94 getcurrentuser(); 95 return true; 96 } catch (error) { 97 // error can be caused by wrong parameters or lack of internet connection 98 alert(`error! ${error message}`); 99 return false; 100 } 101 } catch (error) { 102 console log('error gathering facebook user info, please try again!'); 103 return false; 104 } 105 } 106 }; 107	 108 return ( 109 \<div> 110 \<div classname="header"> 111 \<img 112 classname="header logo" 113 alt="back4app logo" 114 src={ 115 'https //blog back4app com/wp content/uploads/2019/05/back4app white logo 500px png' 116 } 117 /> 118 \<p classname="header text bold">{'react on back4app'}\</p> 119 \<p classname="header text">{'user login'}\</p> 120 \</div> 121 {currentuser === null && ( 122 \<div classname="container"> 123 \<h2 classname="heading">{'user login'}\</h2> 124 \<divider /> 125 \<div classname="form wrapper"> 126 \<input 127 value={username} 128 onchange={(event) => setusername(event target value)} 129 placeholder="username" 130 size="large" 131 classname="form input" 132 /> 133 \<input 134 value={password} 135 onchange={(event) => setpassword(event target value)} 136 placeholder="password" 137 size="large" 138 type="password" 139 classname="form input" 140 /> 141 \</div> 142 \<div classname="form buttons"> 143 \<button 144 onclick={() => douserlogin()} 145 type="primary" 146 classname="form button" 147 color={'#208aec'} 148 size="large" 149 block 150 > 151 log in 152 \</button> 153 \</div> 154 \<divider /> 155 \<div classname="login social"> 156 \<facebooklogin 157 appid="4573670722644997" 158 fields="email" 159 callback={handlefacebookloginloginresponse} 160 render={(renderprops) => ( 161 \<div classname="login social item login social item facebook"> 162 \<img onclick={renderprops onclick} classname="login social item image" src={'https //findicons com/files/icons/2830/clean social icons/250/facebook png'} alt=""/> 163 \</div> 164 )} 165 /> 166 \<div classname="login social item"> 167 \<img classname="login social item image" src={'data\ image/png;base64,ivborw0kggoaaaansuheugaaan8aaadicamaaad5w+jtaaabwvbmvex////qqzu0qfnchft7vauufppk7f08gvr0o/zzofb7uqd7uadpncp/vqdqpzaspk7plhrpoysyoklpoyzpnst97ovwgnskpensxfh8wgavouhplrj+9/b0pad4xsoix5fd7+h74udvenlru0f61tt1r6vuc2vtzvvxiop5zsvpnjb93p4nefofrpeqxpnk5dbus2zt9u++0vtuvyfelfwq1rt2u7j86ejyl5hrsz7/9+x80nt94637xdx8yu//+/d93jb+785sjvwdu/j+9nzc1fvv9p7a5v1frmdl8+nd4spru34zqklohwd0qktwhnpwdjf1ly/5ssl82ibuzjjyidl3pyfswdjwezb1mi7vazn8zwh+68l7wjdq04okszlurkrfuig7tjkgsersq1dsusqateq4o31kk9pjnrq/qmrijuvjmcrho5uyzqvkmmtioqjbqhlesjcm1x3qaaaltuleqvr4no2c2x/a2bwafrnibattyiiwmnusm46begyczdy7ctc47iztdkbjdj1u09ad9v9/qcqeskdlbrpx4pfvys9y+nzovefcbxpcb0hrlh+en9cnzg/lrn+fhieto+nuo9pmlqzkbezpyqhrrzz1zporwm4ddwuilauakhpfb5uiuzyicblsbfsodlm/kysgwv6izihta3l4kkip1670khljvqwjyvooqm2biak1j7f3lb81nbkkap6rnalzpo5vrpbp2okqq3nbowpyiz6kvqa23fkx1dmlwak2jgozovtrkpmt1k5rjguyqk5ugsi3z1h7wrxoza1xqglgflqk8zq975ip3rpn6dkda+r5esfr54vsymd4mjcjtrmmhs6tlc1pshfmpstqnta3vbmo2zloiuw5thch0lmzkqsu6+fhw46kigqhynlasxpmslubr8kd0ba77fboztvyi/oqhtoocx4ossqhlldldnympxyuei2rylhwrmnwi9orlkhpm9uipahqyzvzxojgjirhzx8wz80lspn8z30kxca3l4haj7dexym1k5vsmvg9ceoysm0vsao2yjkzrbfizjedjbxojkt1crgzojeq1cs3d1ypyt/tjddybb0dh3seo8d14qdhmnqn+bugktgb7hzzp45du0y0er2ytdseo3e+28njxcrovwdbvq8rt8pavq8st7mfrf6l9nwi5hrnewtbvh4mcbrs9r/ceuuh5aafmnpkktbjt+7ojnqtvr3e6h2d3xu7ykkgur8vgr65wacicjn/3pi8nijxzyyfsntohpxoiaw+uzhfbtjvwhkr0iyf3b8grhdiyvapcqecujn+fhd8f4awhtfbxvkjgjkboiaotxtf/vwitrlhidtfuybwrhbu8l5rqjp6zcy+tjq7iefl9bbh2slp6hftrowus6h2jvx25gkv6ehxpazsfaqybwotgit9iothtdwkrmdt/exzz6xk9e4wrh+h4/9yfplc5pxk6bsuoxjn/z0lf40e10vuziq2wbsbzfoooai99m6f6hevzx71r6dh5rfrgygsvx3wi0dvhle2rheehgw/rasf8ryjil5kvvwira/l+subezl58hw8odxh/d6afjzjpz58fqgrv2h93qb8y/gz/byqhimjhsct9fjqozqyscdxr2w/mbxv2qzfgpxpumt+brzcscn6pcf5fedwe/jrieetgwxd4mum5rt8fkbpjtfx2ejx6rmcb78jc6gqmmpg8oogtufyjuy6rn8zhk839qzb7wmfkzt4ubdb4qvlutke364e5fxgw8/goz/bzgwnv3og56iqpoy0wmsfwa8vvay1jm2d/ulp4beofb+wfmm43gxoetxcmpvvcpejkhwedbdyyp3cchzhvr1cubefmulvh0tm58hxs200m0kln2tp5cf47tphhysnpv/q4gk5kbqvwl8wjohdz5wjja7bqpixwpymhluezeb/9aksd4b+i4y7l5wtjrtao8vwu48stwo38vwb+qp+n7dwjopew/ilut/gpe0hjdzpdk/utg7e4/k9p0nt4ott6okvofwyehrc4/09gqrpv08e6f4cfjomv/2nywd+bqwx+tgzfnuxkz+o6exgdul89q/tbwj2z8v4yepr80svj5j3unplj4nxe2y/elt7xiqps/przm8r+4fq5sgdwf0o+j2yhxi4t7qj9vrcz285gfpt7xr74epr89tl2w+e0uulkun3co3ghz19uoyf3wldll/muwt5lqogvpucxx4o+r1b8ps8qx6lag+1esfurin67z/uun+igxkn5ffqg98hvw9+bp12fx7zdb+dre/lbe7o9mench5j6q9tp7rbs9t7z51d39rrb7jt+qpss1va6z/w01vllzh7s6v1o9z+ihydq8/p3n+bov5lzv7u3on9wmc7g1skzn9+b99+4i6er6z2d3f1fozx0g9glznnm+sd3b+gbbnypr3cxuigc2bs7hes2hfa90oon99c3u/j/i4hfsvzd7gvfpb3pkzfeh8zkmh1iyhsun/g1t6w39xjr8ha2k3kawdxwpn9i8/zuhxld4c0hn/v+moge4yrmyyqk703eh6r6xmcaiewzf7z0up1mso/k4gbuj4+ae+xw7m5ymri7xjcb3x6bggwhm/+aawho8og8hbm+d13fjj0ak5y00iampe7rzxewgdg9ocfesdsavgczvg9c300oh7o3gqxwgui8k02x2ycwuxs9q/8juqmvh9mejq7f5oapyps6sctpqp6fjcz53rxt8c/qmt/4mxhoabcfpfn4effotkti4fgklif1lrj5hrj096xqm122gdptlfv7qlmel5uftxzk8nrsmxdeyp5bbm+d/wz8ehq39xkkkfvoszpz/nps/x/ndwti1eg0iycmlv9vbxrzgmabuamnah05tbnuohbra4w7mowrzbfu5bamwzj55me7nswobljeqg+hdyt8vwl60xszjvti0rnjqhv2n3s09gj+bqsnoi05phryoh5pie3ngg82umadb1f7wc3dzq+wbwb9f/5alowb8hid9oewmwn85t/bswmgyi3bdsibegwrxvojetnxmzcwhyggs9g+k6t1fdytnkbmzs2uy5byklzz392mrljkh68htlaal7pd3yxuvgr/iw6ge2hh05oj5wtiypaahljiqjvu4kpnk/vsmryrppj+sl5zvsrgp5vcbcp6qic6pxsjj68rdkityf81igyhy/pjff0p2kkvzdwcdwyxzbxr6rcep0yzejthyw+iym6nxfcmqnw9jek5aqih8f1ewveap3ht9laqnx5vymfeotxixb5jeqghmv3my+al3d7d3jb4nq3bgokszduaxox7i9u+897+789ybx1n/n5m8bk0iuh2jgct9v18ug//rno8csg83qxx8tq01bxqzviosn0uuvb0u2/yhluz1vcgyfuak23u6dv8dydvxl1+696+2+ioz3+677tp5eqnbxv0ewm9gn98byoe6fm7x+bcwvibviboyc6fhv1ohr3fsshtxf1ikk+ctbnjcbcatq52bdssx11vr2mqupzrn+v1wr9fn82vq/op2rruav7s97+dnspbrxih9fhxkj4suqgpufpyfwulrysbglmollt5j7mecsbfn7mqgancx6riez4odghnztx8perdcsuj2/cdbza3yyjhmbmjr19xasc8tkgb0n/j1+oigy+bdinkffuf/bjuztbt6aal0hvzga4rfzghllwiotnoqbb9pkxj5wguerdcchi3ljiekmqwzvnjhvvmwzefpkxjzegusgcoer8fscocdqbgetk4cjmkbpuzravmsekxmus4w9/so7ksenfbhy1fltgm7n/ivzxt4hxhestvs+x6jneq5phze1rknrgejdozxyur+kzgf0g6krxz+mmpgveca6ltebxgisshtw9zhecbqee0wunkxr7hfwjvde3ypujuusxopnoo/o0/dgdlyg7aazi56vnyzyh1hla99mhi4/duoiror5o6qi/pdxx69mart3otfkkhjqd76qpq0vkssovq7s/jwdxq2uysusufuftg0udq6k4qrgymzfigoe4ngixfuepm7zxi6qhulplbmcxhpafijlk37p2wlorsiqvjv2dm/ikfsbb96uq0yvtmbmpm4jzhhsomhec7musrfyzjxt0mep6ctcox5qsqo1+gobobi6vzmkzltsma+prfot2lwvmqbwnvycbepfi2b9xb7x5g0vy9lsubbndwaa6zvmpgygwrm3g1dfgkqnforrc+jm3rtzvepkriayhnzc1i5sdsmlk/whcjdwqyatpyaaaaabjru5erkjggg=='} alt=""/> 168 \</div> 169 \<div classname="login social item"> 170 \<img classname="login social item image" src={'data\ image/png;base64,ivborw0kggoaaaansuheugaaaoeaaadhcamaaaajbsjiaaaav1bmvewzmzn///+skpkvlzwrkzh19fwgokdg4ocampqjo6p8/py+vr7l5ex29vb5+fniymirq6vq0ndp6enw1ta3t7fu1ns7u7uwsldkysrv7+/b29vi4uktra2ojcyuaaajguleqvr4no2d6zrqiaygkdsldrsrvh3v/zppq6pjjculxhlnod9/av8lauistkjsq8oxaetzfgjkclqhrboojxxoglcvae0dyz33doyitxdoubnhnrvhdysfqjoacfd7c4f39whxhfvj99cig/obryesbbpwqjjl7apfn7kl1rifmfavziebchzq2fqgdqwe9cgi/ckcctqfn/cyevh6sbqfnxapajysd4hnwacalpd4qmtc3gnjlsnqwprgjiwgqjnkgjq4hbxqrxvnrr4sk/atbpqzhjejd2ax7yfhh8hjihloyudjzb4tjzd3rwrko2k8wgu8chtlkreoteirrha+yzkhj8uibje+amwj9krihb9yh5vzdq+krijzurkhxllxclfivnhrjfwsoityijqbhzeik5rqzkl6vhrctiukogiud5nriix0flpw8gkxcffdkmdmkiieh9gntd8lhxebcdfrkvtleqixliq1il0+try5gj6rturwss+bnhdzf0pofgdnt7geavmrd+k9jiecwq5esqx3tzmthihcfwbot1gaw/avgnmtdocrer+dgyynzpye0lb0oskjfz3uzzvxphbqwpxhqzpkltxundxhbjtqgdhf9g9pihsv+4cjbkkxtilnhd5ntbj5rejs7vdaj05us9mfny+rxmrbvzu54rebc9acqhd/vssdj3jgd+3mvcq2agpjzwyg2nemr9d/qprwh89j0xwxn/xsactxwgyltpzp+53ymju1exu8pnxm04shbv4uba/befibumwzn6ewpk5kc27p29worbp5uw02sk8rbo6tsw+xy/1bwddv3j3cotpz612xu9s0x6bv+qthsxpenxqm8mvox2weijnq1rvf1wysx0mjz4vbzwd7v9prxmm2n6foadt1byu4zsywwtko/cevr2qkzaqds2jb1xz3pmyqwg2v7/jkabb1dqbdjnefr8acmyadccvwf355p24x0tcqkym986e9hsuktvjp2x/6on7u/aptc/l8381lzfpnjczxmbgp+nlt11x3gr3tdpt8n6xufboe4tp76rwgduv2qooonxpwwalrikx48fx7myftopvbpj7kiurceqdxsoljyrcgd8gxitiy6yrduov7nsyoscbsxeapqhbekqfsqaiikxcnsytehjkbgigc+rfz6dikkeny6loi93kgz5xcenanietgeahxcpsealmomggbuk0zvclbysc4yapzypwftxgoirz/okbudrtjumiyngeiu0mameiwweeb8o0fqrhsbmucvkveckeijg0i+pphqt1mxs0pfgyyem2/iiosiew4hvyirxpaitjiqpstep37ekhquwipb4oqowzdso/uhagvf0jgtgza2cj+hiycdibq8yo0zzzq+wkv7+xztfj8hirtdcv/0k+i59dfusoqmoelxopyrfthafqt7tv2uvjcjxcqtatcffof4uztj+xmfbchxu/fiqfojcsqx0qto3xir6h3rmac+gjxwjsppw3aq4gl60ytp4nwq6h3nuqc+gi1+i8c5ueme2o1ni6fhokh1lpzcqjzok6odtm9zan6cbdacxnbcoaqlwiuryelzmcjte7vawynh1drzbfsngocuovmma2oezjoqhu6taezfeoewinoaialcuk8mgukhzrxgyvckzu0corqj9x+e/4nvokvlbzfjdak0+69cmvmfl2eafno72vpxfbeagnfdk9q1zrio2c161itujx23p7gbveqymp/r/1hsonpcukgbfxcwtgdie4ilp6lqwbtm06o9nw0oatvokheoyf+dunjhhqd9vh3jowtoiw344ndtccjfqd4sxffnh2x2l7kp8j3ekqdepl7rn8pd2wov7gxpb9dpilh3pzgivr7rgry6xopodo98cdlqmrm817fpodei7/0ez5iy0bihuh7clwec1/e8qz7cdwbgl5oli9wrxfdnohxsytxt67wkxerxaudrijddxnbzj+ul/connbr4729hkrn/ehuwfeds4k+hfztwaj1eqouoih6cxxpigdzskf1e2ovgdhilfhocjg3vr00/zkbo/miqlh9g49iykebcbu73o6fxf8brtcodkfdcykybbgqdtbccywubrgqdcl4kfv6rymyg/mm3xsqlx1hgidh23ttqwk5xv/9jevtpgjcgw5himmnab+v50qdjtr7jjgitwo0tpgoa9obpcelsdyjdl/gnzynnh1cwl+prfhvv8riutxv9k/ynpxihfqz2b7klbwaeb6nrffmjqkr0/rdnwdz74u2kkhiykr38jui8eh3ttfu97l+mqy4oelootv535+qwfageygoponaqlduzu0weh1kfor6wr+mzqaqbrv/rda2mprjfjsaerzqriju/hftml6glg2mnfp5lcrakuaoura+g0okibl9is0pfuzgjfr8mih8qvjdqwq9bmi4kzvq7xyde3nyzq3scifapojlunfjiccn0lojk43ghhchycj/vrilcos6uqxchb5tsjoij4dfnqocljjaivr3trupvjhvh2ghq5+mpfu6ezumve2kxobehqgqfuoe7ih5lcj7sk165tzduzolqe4ryvd80tlvl6n5xwxcjtuz0pfdpj4knxqgiuee4hdczb9/ce5k+uugvf6kf6kl5rl4ljc6taepwldctdyjp2vvhqgijjtuynn56mgesr0pkblrfsbmpmlngy5bnikumnbdao54j6aayatniu1wrxncpj6ej3yvpxhhmltyp35nbwrkrmtp2tjnlfvnaybpeszjyxhhz+fdfnexfbb+qdrdobtcs3qecjocnhiddv0zmqfu7zmqjjyc49gthmnroe/n7dkhfeazkksjkce1ewc9s5iss3dacnbscm/7ovgix9kwaexyz3qameka4305z1tqcbnpfmb0vhbnggqik1u++nlolg1nel415tikc0va7dmrjaj7rpq7x33vpvnfvzfltu3sl8resowhhfqsgcjex1p/lu7yl1vtbeb9qd6fjo05b1k7z1nxoy5ijldvzfu2b09lvzqb1x5/alyvmmpfht+c/6dv/qmh/ovcu90claaaaabjru5erkjggg=='} alt=""/> 171 \</div> 172 \</div> 173 \<p classname="form hint">don't have an account? \<a classname="form link" href="#">sign up\</a>\</p> 174 \</div> 175 )} 176 {currentuser !== null && ( 177 \<div classname="container"> 178 \<h2 classname="heading">{'user screen'}\</h2> 179 \<divider /> 180 \<h2 classname="heading">{`hello ${currentuser get('username')}!`}\</h2> 181 \<div classname="form buttons"> 182 \<button 183 onclick={() => douserlogout()} 184 type="primary" 185 classname="form button" 186 color={'#208aec'} 187 size="large" 188 block 189 > 190 log out 191 \</button> 192 \</div> 193 \</div> 194 )} 195 \</div> 196 ); 197 };1 import react, { usestate, fc, reactelement } from 'react'; 2 import ' /app css'; 3 import { button, divider, input } from 'antd'; 4 import facebooklogin from 'react facebook login/dist/facebook login render props'; 5 const parse = require('parse/dist/parse min js'); 6	 7 export const userlogin fc<{}> = () reactelement => { 8 // state variables 9 const \[username, setusername] = usestate(''); 10 const \[password, setpassword] = usestate(''); 11 const \[currentuser, setcurrentuser] = usestate\<parse object | null>(null); 12	 13 const douserlogin = async function () promise\<boolean> { 14 // note that these values come from state variables that we've declared before 15 const usernamevalue string = username; 16 const passwordvalue string = password; 17 try { 18 const loggedinuser parse user = await parse user login(usernamevalue, passwordvalue); 19 // login returns the corresponding parseuser object 20 alert( 21 `success! user ${loggedinuser get('username')} has successfully signed in!`, 22 ); 23 // to verify that this is in fact the current user, `current` can be used 24 const currentuser parse user = await parse user current(); 25 console log(loggedinuser === currentuser); 26 // clear input fields 27 setusername(''); 28 setpassword(''); 29 // update state variable holding current user 30 getcurrentuser(); 31 return true; 32 } catch (error any) { 33 // error can be caused by wrong parameters or lack of internet connection 34 alert(`error! ${error message}`); 35 return false; 36 } 37 }; 38	 39 const douserlogout = async function () promise\<boolean> { 40 try { 41 await parse user logout(); 42 // to verify that current user is now empty, currentasync can be used 43 const currentuser parse user = await parse user current(); 44 if (currentuser === null) { 45 alert('success! no user is logged in anymore!'); 46 } 47 // update state variable holding current user 48 getcurrentuser(); 49 return true; 50 } catch (error any) { 51 alert(`error! ${error message}`); 52 return false; 53 } 54 }; 55	 56 // function that will return current user and also update current username 57 const getcurrentuser = async function () promise\<parse user | null> { 58 const currentuser (parse user | null) = await parse user current(); 59 // update state variable holding current user 60 setcurrentuser(currentuser); 61 return currentuser; 62 } 63	 64 const handlefacebookloginloginresponse = async function(response any) promise\<boolean> { 65 // check if response has an error 66 if (response error !== undefined) { 67 console log(`error ${response error}`); 68 return false; 69 } else { 70 try { 71 // gather facebook user info 72 const userid string = response id; 73 const useremail string = response email; 74 const useraccesstoken string = response accesstoken; 75 // try to login on parse using linkwith and these credentials 76 // create a new parse user object 77 const usertologin parse user = new parse user(); 78 // set username and email to match facebook profile email 79 usertologin set('username', useremail); 80 usertologin set('email', useremail); 81 try { 82 let loggedinuser parse user = await usertologin 83 linkwith('facebook', { 84 authdata {id userid, access token useraccesstoken}, 85 }); 86 // login returns the corresponding parseuser object 87 alert( 88 `success! user ${loggedinuser get('username')} has successfully signed in!`, 89 ); 90 // update state variable holding current user 91 getcurrentuser(); 92 return true; 93 } catch (error any) { 94 // error can be caused by wrong parameters or lack of internet connection 95 alert(`error! ${error message}`); 96 return false; 97 } 98 } catch (error any) { 99 console log("error gathering facebook user info, please try again!") 100 return false; 101 } 102 } 103 } 104	 105 return ( 106 \<div> 107 \<div classname="header"> 108 \<img 109 classname="header logo" 110 alt="back4app logo" 111 src={ 112 'https //blog back4app com/wp content/uploads/2019/05/back4app white logo 500px png' 113 } 114 /> 115 \<p classname="header text bold">{'react on back4app'}\</p> 116 \<p classname="header text">{'user login'}\</p> 117 \</div> 118 {currentuser === null && ( 119 \<div classname="container"> 120 \<h2 classname="heading">{'user login'}\</h2> 121 \<divider /> 122 \<div classname="form wrapper"> 123 \<input 124 value={username} 125 onchange={(event) => setusername(event target value)} 126 placeholder="username" 127 size="large" 128 classname="form input" 129 /> 130 \<input 131 value={password} 132 onchange={(event) => setpassword(event target value)} 133 placeholder="password" 134 size="large" 135 type="password" 136 classname="form input" 137 /> 138 \</div> 139 \<div classname="form buttons"> 140 \<button 141 onclick={() => douserlogin()} 142 type="primary" 143 classname="form button" 144 color={'#208aec'} 145 size="large" 146 block 147 > 148 log in 149 \</button> 150 \</div> 151 \<divider /> 152 \<div classname="login social"> 153 \<facebooklogin 154 appid="4573670722644997" 155 fields="email" 156 callback={handlefacebookloginloginresponse} 157 render={(renderprops {onclick () => void}) => ( 158 \<div classname="login social item login social item facebook"> 159 \<img onclick={renderprops onclick} classname="login social item image" src={'https //findicons com/files/icons/2830/clean social icons/250/facebook png'} alt=""/> 160 \</div> 161 )} 162 /> 163 \<div classname="login social item"> 164 \<img classname="login social item image" src={'data\ image/png;base64,ivborw0kggoaaaansuheugaaan8aaadicamaaad5w+jtaaabwvbmvex////qqzu0qfnchft7vauufppk7f08gvr0o/zzofb7uqd7uadpncp/vqdqpzaspk7plhrpoysyoklpoyzpnst97ovwgnskpensxfh8wgavouhplrj+9/b0pad4xsoix5fd7+h74udvenlru0f61tt1r6vuc2vtzvvxiop5zsvpnjb93p4nefofrpeqxpnk5dbus2zt9u++0vtuvyfelfwq1rt2u7j86ejyl5hrsz7/9+x80nt94637xdx8yu//+/d93jb+785sjvwdu/j+9nzc1fvv9p7a5v1frmdl8+nd4spru34zqklohwd0qktwhnpwdjf1ly/5ssl82ibuzjjyidl3pyfswdjwezb1mi7vazn8zwh+68l7wjdq04okszlurkrfuig7tjkgsersq1dsusqateq4o31kk9pjnrq/qmrijuvjmcrho5uyzqvkmmtioqjbqhlesjcm1x3qaaaltuleqvr4no2c2x/a2bwafrnibattyiiwmnusm46begyczdy7ctc47iztdkbjdj1u09ad9v9/qcqeskdlbrpx4pfvys9y+nzovefcbxpcb0hrlh+en9cnzg/lrn+fhieto+nuo9pmlqzkbezpyqhrrzz1zporwm4ddwuilauakhpfb5uiuzyicblsbfsodlm/kysgwv6izihta3l4kkip1670khljvqwjyvooqm2biak1j7f3lb81nbkkap6rnalzpo5vrpbp2okqq3nbowpyiz6kvqa23fkx1dmlwak2jgozovtrkpmt1k5rjguyqk5ugsi3z1h7wrxoza1xqglgflqk8zq975ip3rpn6dkda+r5esfr54vsymd4mjcjtrmmhs6tlc1pshfmpstqnta3vbmo2zloiuw5thch0lmzkqsu6+fhw46kigqhynlasxpmslubr8kd0ba77fboztvyi/oqhtoocx4ossqhlldldnympxyuei2rylhwrmnwi9orlkhpm9uipahqyzvzxojgjirhzx8wz80lspn8z30kxca3l4haj7dexym1k5vsmvg9ceoysm0vsao2yjkzrbfizjedjbxojkt1crgzojeq1cs3d1ypyt/tjddybb0dh3seo8d14qdhmnqn+bugktgb7hzzp45du0y0er2ytdseo3e+28njxcrovwdbvq8rt8pavq8st7mfrf6l9nwi5hrnewtbvh4mcbrs9r/ceuuh5aafmnpkktbjt+7ojnqtvr3e6h2d3xu7ykkgur8vgr65wacicjn/3pi8nijxzyyfsntohpxoiaw+uzhfbtjvwhkr0iyf3b8grhdiyvapcqecujn+fhd8f4awhtfbxvkjgjkboiaotxtf/vwitrlhidtfuybwrhbu8l5rqjp6zcy+tjq7iefl9bbh2slp6hftrowus6h2jvx25gkv6ehxpazsfaqybwotgit9iothtdwkrmdt/exzz6xk9e4wrh+h4/9yfplc5pxk6bsuoxjn/z0lf40e10vuziq2wbsbzfoooai99m6f6hevzx71r6dh5rfrgygsvx3wi0dvhle2rheehgw/rasf8ryjil5kvvwira/l+subezl58hw8odxh/d6afjzjpz58fqgrv2h93qb8y/gz/byqhimjhsct9fjqozqyscdxr2w/mbxv2qzfgpxpumt+brzcscn6pcf5fedwe/jrieetgwxd4mum5rt8fkbpjtfx2ejx6rmcb78jc6gqmmpg8oogtufyjuy6rn8zhk839qzb7wmfkzt4ubdb4qvlutke364e5fxgw8/goz/bzgwnv3og56iqpoy0wmsfwa8vvay1jm2d/ulp4beofb+wfmm43gxoetxcmpvvcpejkhwedbdyyp3cchzhvr1cubefmulvh0tm58hxs200m0kln2tp5cf47tphhysnpv/q4gk5kbqvwl8wjohdz5wjja7bqpixwpymhluezeb/9aksd4b+i4y7l5wtjrtao8vwu48stwo38vwb+qp+n7dwjopew/ilut/gpe0hjdzpdk/utg7e4/k9p0nt4ott6okvofwyehrc4/09gqrpv08e6f4cfjomv/2nywd+bqwx+tgzfnuxkz+o6exgdul89q/tbwj2z8v4yepr80svj5j3unplj4nxe2y/elt7xiqps/przm8r+4fq5sgdwf0o+j2yhxi4t7qj9vrcz285gfpt7xr74epr89tl2w+e0uulkun3co3ghz19uoyf3wldll/muwt5lqogvpucxx4o+r1b8ps8qx6lag+1esfurin67z/uun+igxkn5ffqg98hvw9+bp12fx7zdb+dre/lbe7o9mench5j6q9tp7rbs9t7z51d39rrb7jt+qpss1va6z/w01vllzh7s6v1o9z+ihydq8/p3n+bov5lzv7u3on9wmc7g1skzn9+b99+4i6er6z2d3f1fozx0g9glznnm+sd3b+gbbnypr3cxuigc2bs7hes2hfa90oon99c3u/j/i4hfsvzd7gvfpb3pkzfeh8zkmh1iyhsun/g1t6w39xjr8ha2k3kawdxwpn9i8/zuhxld4c0hn/v+moge4yrmyyqk703eh6r6xmcaiewzf7z0up1mso/k4gbuj4+ae+xw7m5ymri7xjcb3x6bggwhm/+aawho8og8hbm+d13fjj0ak5y00iampe7rzxewgdg9ocfesdsavgczvg9c300oh7o3gqxwgui8k02x2ycwuxs9q/8juqmvh9mejq7f5oapyps6sctpqp6fjcz53rxt8c/qmt/4mxhoabcfpfn4effotkti4fgklif1lrj5hrj096xqm122gdptlfv7qlmel5uftxzk8nrsmxdeyp5bbm+d/wz8ehq39xkkkfvoszpz/nps/x/ndwti1eg0iycmlv9vbxrzgmabuamnah05tbnuohbra4w7mowrzbfu5bamwzj55me7nswobljeqg+hdyt8vwl60xszjvti0rnjqhv2n3s09gj+bqsnoi05phryoh5pie3ngg82umadb1f7wc3dzq+wbwb9f/5alowb8hid9oewmwn85t/bswmgyi3bdsibegwrxvojetnxmzcwhyggs9g+k6t1fdytnkbmzs2uy5byklzz392mrljkh68htlaal7pd3yxuvgr/iw6ge2hh05oj5wtiypaahljiqjvu4kpnk/vsmryrppj+sl5zvsrgp5vcbcp6qic6pxsjj68rdkityf81igyhy/pjff0p2kkvzdwcdwyxzbxr6rcep0yzejthyw+iym6nxfcmqnw9jek5aqih8f1ewveap3ht9laqnx5vymfeotxixb5jeqghmv3my+al3d7d3jb4nq3bgokszduaxox7i9u+897+789ybx1n/n5m8bk0iuh2jgct9v18ug//rno8csg83qxx8tq01bxqzviosn0uuvb0u2/yhluz1vcgyfuak23u6dv8dydvxl1+696+2+ioz3+677tp5eqnbxv0ewm9gn98byoe6fm7x+bcwvibviboyc6fhv1ohr3fsshtxf1ikk+ctbnjcbcatq52bdssx11vr2mqupzrn+v1wr9fn82vq/op2rruav7s97+dnspbrxih9fhxkj4suqgpufpyfwulrysbglmollt5j7mecsbfn7mqgancx6riez4odghnztx8perdcsuj2/cdbza3yyjhmbmjr19xasc8tkgb0n/j1+oigy+bdinkffuf/bjuztbt6aal0hvzga4rfzghllwiotnoqbb9pkxj5wguerdcchi3ljiekmqwzvnjhvvmwzefpkxjzegusgcoer8fscocdqbgetk4cjmkbpuzravmsekxmus4w9/so7ksenfbhy1fltgm7n/ivzxt4hxhestvs+x6jneq5phze1rknrgejdozxyur+kzgf0g6krxz+mmpgveca6ltebxgisshtw9zhecbqee0wunkxr7hfwjvde3ypujuusxopnoo/o0/dgdlyg7aazi56vnyzyh1hla99mhi4/duoiror5o6qi/pdxx69mart3otfkkhjqd76qpq0vkssovq7s/jwdxq2uysusufuftg0udq6k4qrgymzfigoe4ngixfuepm7zxi6qhulplbmcxhpafijlk37p2wlorsiqvjv2dm/ikfsbb96uq0yvtmbmpm4jzhhsomhec7musrfyzjxt0mep6ctcox5qsqo1+gobobi6vzmkzltsma+prfot2lwvmqbwnvycbepfi2b9xb7x5g0vy9lsubbndwaa6zvmpgygwrm3g1dfgkqnforrc+jm3rtzvepkriayhnzc1i5sdsmlk/whcjdwqyatpyaaaaabjru5erkjggg=='} alt=""/> 165 \</div> 166 \<div classname="login social item"> 167 \<img classname="login social item image" src={'data\ image/png;base64,ivborw0kggoaaaansuheugaaaoeaaadhcamaaaajbsjiaaaav1bmvewzmzn///+skpkvlzwrkzh19fwgokdg4ocampqjo6p8/py+vr7l5ex29vb5+fniymirq6vq0ndp6enw1ta3t7fu1ns7u7uwsldkysrv7+/b29vi4uktra2ojcyuaaajguleqvr4no2d6zrqiaygkdsldrsrvh3v/zppq6pjjculxhlnod9/av8lauistkjsq8oxaetzfgjkclqhrboojxxoglcvae0dyz33doyitxdoubnhnrvhdysfqjoacfd7c4f39whxhfvj99cig/obryesbbpwqjjl7apfn7kl1rifmfavziebchzq2fqgdqwe9cgi/ckcctqfn/cyevh6sbqfnxapajysd4hnwacalpd4qmtc3gnjlsnqwprgjiwgqjnkgjq4hbxqrxvnrr4sk/atbpqzhjejd2ax7yfhh8hjihloyudjzb4tjzd3rwrko2k8wgu8chtlkreoteirrha+yzkhj8uibje+amwj9krihb9yh5vzdq+krijzurkhxllxclfivnhrjfwsoityijqbhzeik5rqzkl6vhrctiukogiud5nriix0flpw8gkxcffdkmdmkiieh9gntd8lhxebcdfrkvtleqixliq1il0+try5gj6rturwss+bnhdzf0pofgdnt7geavmrd+k9jiecwq5esqx3tzmthihcfwbot1gaw/avgnmtdocrer+dgyynzpye0lb0oskjfz3uzzvxphbqwpxhqzpkltxundxhbjtqgdhf9g9pihsv+4cjbkkxtilnhd5ntbj5rejs7vdaj05us9mfny+rxmrbvzu54rebc9acqhd/vssdj3jgd+3mvcq2agpjzwyg2nemr9d/qprwh89j0xwxn/xsactxwgyltpzp+53ymju1exu8pnxm04shbv4uba/befibumwzn6ewpk5kc27p29worbp5uw02sk8rbo6tsw+xy/1bwddv3j3cotpz612xu9s0x6bv+qthsxpenxqm8mvox2weijnq1rvf1wysx0mjz4vbzwd7v9prxmm2n6foadt1byu4zsywwtko/cevr2qkzaqds2jb1xz3pmyqwg2v7/jkabb1dqbdjnefr8acmyadccvwf355p24x0tcqkym986e9hsuktvjp2x/6on7u/aptc/l8381lzfpnjczxmbgp+nlt11x3gr3tdpt8n6xufboe4tp76rwgduv2qooonxpwwalrikx48fx7myftopvbpj7kiurceqdxsoljyrcgd8gxitiy6yrduov7nsyoscbsxeapqhbekqfsqaiikxcnsytehjkbgigc+rfz6dikkeny6loi93kgz5xcenanietgeahxcpsealmomggbuk0zvclbysc4yapzypwftxgoirz/okbudrtjumiyngeiu0mameiwweeb8o0fqrhsbmucvkveckeijg0i+pphqt1mxs0pfgyyem2/iiosiew4hvyirxpaitjiqpstep37ekhquwipb4oqowzdso/uhagvf0jgtgza2cj+hiycdibq8yo0zzzq+wkv7+xztfj8hirtdcv/0k+i59dfusoqmoelxopyrfthafqt7tv2uvjcjxcqtatcffof4uztj+xmfbchxu/fiqfojcsqx0qto3xir6h3rmac+gjxwjsppw3aq4gl60ytp4nwq6h3nuqc+gi1+i8c5ueme2o1ni6fhokh1lpzcqjzok6odtm9zan6cbdacxnbcoaqlwiuryelzmcjte7vawynh1drzbfsngocuovmma2oezjoqhu6taezfeoewinoaialcuk8mgukhzrxgyvckzu0corqj9x+e/4nvokvlbzfjdak0+69cmvmfl2eafno72vpxfbeagnfdk9q1zrio2c161itujx23p7gbveqymp/r/1hsonpcukgbfxcwtgdie4ilp6lqwbtm06o9nw0oatvokheoyf+dunjhhqd9vh3jowtoiw344ndtccjfqd4sxffnh2x2l7kp8j3ekqdepl7rn8pd2wov7gxpb9dpilh3pzgivr7rgry6xopodo98cdlqmrm817fpodei7/0ez5iy0bihuh7clwec1/e8qz7cdwbgl5oli9wrxfdnohxsytxt67wkxerxaudrijddxnbzj+ul/connbr4729hkrn/ehuwfeds4k+hfztwaj1eqouoih6cxxpigdzskf1e2ovgdhilfhocjg3vr00/zkbo/miqlh9g49iykebcbu73o6fxf8brtcodkfdcykybbgqdtbccywubrgqdcl4kfv6rymyg/mm3xsqlx1hgidh23ttqwk5xv/9jevtpgjcgw5himmnab+v50qdjtr7jjgitwo0tpgoa9obpcelsdyjdl/gnzynnh1cwl+prfhvv8riutxv9k/ynpxihfqz2b7klbwaeb6nrffmjqkr0/rdnwdz74u2kkhiykr38jui8eh3ttfu97l+mqy4oelootv535+qwfageygoponaqlduzu0weh1kfor6wr+mzqaqbrv/rda2mprjfjsaerzqriju/hftml6glg2mnfp5lcrakuaoura+g0okibl9is0pfuzgjfr8mih8qvjdqwq9bmi4kzvq7xyde3nyzq3scifapojlunfjiccn0lojk43ghhchycj/vrilcos6uqxchb5tsjoij4dfnqocljjaivr3trupvjhvh2ghq5+mpfu6ezumve2kxobehqgqfuoe7ih5lcj7sk165tzduzolqe4ryvd80tlvl6n5xwxcjtuz0pfdpj4knxqgiuee4hdczb9/ce5k+uugvf6kf6kl5rl4ljc6taepwldctdyjp2vvhqgijjtuynn56mgesr0pkblrfsbmpmlngy5bnikumnbdao54j6aayatniu1wrxncpj6ej3yvpxhhmltyp35nbwrkrmtp2tjnlfvnaybpeszjyxhhz+fdfnexfbb+qdrdobtcs3qecjocnhiddv0zmqfu7zmqjjyc49gthmnroe/n7dkhfeazkksjkce1ewc9s5iss3dacnbscm/7ovgix9kwaexyz3qameka4305z1tqcbnpfmb0vhbnggqik1u++nlolg1nel415tikc0va7dmrjaj7rpq7x33vpvnfvzfltu3sl8resowhhfqsgcjex1p/lu7yl1vtbeb9qd6fjo05b1k7z1nxoy5ijldvzfu2b09lvzqb1x5/alyvmmpfht+c/6dv/qmh/ovcu90claaaaabjru5erkjggg=='} alt=""/> 168 \</div> 169 \</div> 170 \<p classname="form hint">don't have an account? \<a classname="form link" href="#">sign up\</a>\</p> 171 \</div> 172 )} 173 {currentuser !== null && ( 174 \<div classname="container"> 175 \<h2 classname="heading">{'user screen'}\</h2> 176 \<divider /> 177 \<h2 classname="heading">{`hello ${currentuser get('username')}!`}\</h2> 178 \<div classname="form buttons"> 179 \<button 180 onclick={() => douserlogout()} 181 type="primary" 182 classname="form button" 183 color={'#208aec'} 184 size="large" 185 block 186 > 187 log out 188 \</button> 189 \</div> 190 \</div> 191 )} 192 \</div> 193 ); 194 }; добавьте эти классы в ваш app css app css файл, если вы хотите полностью отобразить макет этого компонента app css 1 @import ' antd/dist/antd css'; 2	 3 app { 4 text align center; 5 } 6	 7 html { 8 box sizing border box; 9 outline none; 10 overflow auto; 11 } 12	 13 , 14 before, 15 after { 16 margin 0; 17 padding 0; 18 box sizing inherit; 19 } 20	 21 h1, 22 h2, 23 h3, 24 h4, 25 h5, 26 h6 { 27 margin 0; 28 font weight bold; 29 } 30	 31 p { 32 margin 0; 33 } 34	 35 body { 36 margin 0; 37 background color #fff; 38 } 39	 40 container { 41 width 100%; 42 max width 900px; 43 margin auto; 44 padding 20px 0; 45 text align left; 46 } 47	 48 header { 49 align items center; 50 padding 25px 0; 51 background color #208aec; 52 } 53	 54 header logo { 55 height 55px; 56 margin bottom 20px; 57 object fit contain; 58 } 59	 60 header text bold { 61 margin bottom 3px; 62 color rgba(255, 255, 255, 0 9); 63 font size 16px; 64 font weight bold; 65 } 66	 67 header text { 68 color rgba(255, 255, 255, 0 9); 69 font size 15px; 70 } 71	 72 heading { 73 font size 22px; 74 } 75	 76 flex { 77 display flex; 78 } 79	 80 flex between { 81 display flex; 82 justify content space between; 83 } 84	 85 flex child { 86 flex 0 0 45%; 87 } 88	 89 heading button { 90 margin left 12px; 91 } 92	 93 list item { 94 padding bottom 15px; 95 margin bottom 15px; 96 border bottom 1px solid rgba(0, 0, 0, 0 06); 97 text align left; 98 } 99	 100 list item title { 101 color rgba(0, 0, 0, 0 87); 102 font size 17px; 103 } 104	 105 list item description { 106 color rgba(0, 0, 0, 0 5); 107 font size 15px; 108 } 109	 110 form input { 111 margin bottom 20px; 112 } 113	 114 login social { 115 display flex; 116 justify content center; 117 margin bottom 30px; 118 } 119	 120 login social item { 121 width 54px; 122 height 54px; 123 border radius 54px; 124 padding 12px; 125 margin 0 12px; 126 border 1px solid #e6e6e6; 127 box shadow 0 2px 4px #d6d6d6; 128 } 129	 130 login social item facebook { 131 padding 4px; 132 background color #3c5b9b; 133 } 134	 135 login social item image { 136 width 100%; 137 } 138	 139 form hint { 140 color rgba(0, 0, 0, 0 5); 141 font size 16px; 142 text align center; 143 } продолжайте и протестируйте вашу новую функцию если вам удалось войти в facebook и вызов linkwith linkwith прошел успешно, вы должны увидеть сообщение об успехе, подобное этому 3 проверка входа пользователя и создание сессии чтобы убедиться, что вход через facebook сработал, вы можете посмотреть на свою панель управления parse и увидеть своего нового пользователя пользователя (если ваши данные аутентификации facebook не принадлежали другому пользователю), содержащего параметры authdata authdata facebook вы также можете проверить, что в панели управления была создана действительная сессия, содержащая указатель на этот пользователь пользователь объект 4 связывание существующего пользователя с входом через facebook другим linkwith linkwith возможным использованием является связывание существующего пользователя с другим провайдером аутентификации, в данном случае, facebook добавьте эту функцию, которая вызывает linkwith linkwith так же, как и вход в ваш userlogin userlogin компонент единственное отличие здесь в том, что вместо вызова метода из пустого parse user parse user , вы будете использовать его из объекта текущего вошедшего пользователя javascript 1 const handlefacebookloginlinkresponse = async function(response) { 2 // check if response has an error 3 if (response error !== undefined) { 4 console log(`error ${response error}`); 5 return false; 6 } else { 7 try { 8 // gather facebook user info 9 const userid = response id; 10 const useraccesstoken = response accesstoken; 11 // try to link current parse user using linkwith and these credentials 12 // get current user 13 const usertolink = await parse user current(); 14 try { 15 let loggedinuser = await usertolink 16 linkwith('facebook', { 17 authdata {id userid, access token useraccesstoken}, 18 }); 19 // login returns the corresponding parseuser object 20 alert( 21 `success! user ${loggedinuser get( 22 'username', 23 )} has successfully linked his facebook account!`, 24 ); 25 // update state variable holding current user 26 getcurrentuser(); 27 return true; 28 } catch (error) { 29 // error can be caused by wrong parameters or lack of internet connection 30 alert(`error! ${error message}`); 31 return false; 32 } 33 } catch (error) { 34 console log("error gathering facebook user info, please try again!") 35 return false; 36 } 37 } 38 }1 const handlefacebookloginlinkresponse = async function(response any) promise\<boolean> { 2 // check if response has an error 3 if (response error !== undefined) { 4 console log(`error ${response error}`); 5 return false; 6 } else { 7 try { 8 // gather facebook user info 9 const userid string = response id; 10 const useraccesstoken string = response accesstoken; 11 // try to link current parse user using linkwith and these credentials 12 // get current user 13 const usertolink parse user = await parse user current(); 14 try { 15 let loggedinuser parse user = await usertolink 16 linkwith('facebook', { 17 authdata {id userid, access token useraccesstoken}, 18 }); 19 // login returns the corresponding parseuser object 20 alert( 21 `success! user ${loggedinuser get( 22 'username', 23 )} has successfully linked his facebook account!`, 24 ); 25 // update state variable holding current user 26 getcurrentuser(); 27 return true; 28 } catch (error any) { 29 // error can be caused by wrong parameters or lack of internet connection 30 alert(`error! ${error message}`); 31 return false; 32 } 33 } catch (error any) { 34 console log("error gathering facebook user info, please try again!") 35 return false; 36 } 37 } 38 } назначьте эту функцию другому react facebook login react facebook login компоненту на вашем главном экране, который отображается только когда в вашем приложении есть текущий пользователь протестируйте вашу новую функцию, отметив, что значение объекта parse user parse user authdata authdata будет обновлено новыми данными провайдера аутентификации убедитесь, что пользователь действительно обновился в вашей панели управления parse заключение в конце этого руководства вы узнали, как войти в систему, зарегистрироваться или связать существующих пользователей parse на react, используя facebook login с react google login react google login в следующем руководстве мы покажем вам, как использовать вход с apple