Theory
Client ની તપાસ પૂરતી નહોતી
Portal નું registration form submit કરતાં પહેલાં email ખરું લાગે છે કે નહીં એ તપાસવા થોડું JavaScript વાપરે છે. પણ કોઈ વિદ્યાર્થી JavaScript બંધ કરી દે, કે request જાતે ઘડી કાઢે, અને સીધો કચરો તમારા PHP સુધી મોકલી દે.
એટલે જ એક નિયમ લોખંડી છે: client બાજુની ચકાસણી સગવડ છે, server બાજુની ચકાસણી જ ખરી સલામતી છે. Browser ની તપાસ હંમેશા ટાળી શકાય છે; server ની તપાસ નહીં. આ પાઠ portal ને PHP ના filter_var થી બરાબર server બાજુની ચકાસણી આપે છે, અને એને JSON બોલતાં શીખવે છે, એટલે કે દરેક આધુનિક front-end અને API વાપરે છે તે ઘાટ.
Theory
filter_var: ચકાસવું અને સાફ કરવું
PHP સાથે એક filter engine આવે છે જ્યાં filter_var($value, FILTER_...) દ્વારા પહોંચાય છે:
- FILTER_VALIDATE_EMAIL: ખરું હોય તો email પાછું આપે છે, નહીં તો false
- FILTER_VALIDATE_INT, FILTER_VALIDATE_URL: સંખ્યાઓ અને URLs માટે એ જ વિચાર
- FILTER_SANITIZE_...: તપાસવાને બદલે સાફ કરે છે (અનિચ્છનીય અક્ષરો કાઢી નાખે છે)
ઢબ આવી છે: if (filter_var($email, FILTER_VALIDATE_EMAIL)) { ... } else { echo "Invalid email"; }. ખરું પરિણામ કિંમત હોય છે અને ખોટું false હોય છે, એટલે આ સાફ વંચાય છે. Server પર ચકાસણી કરવાની આ પ્રમાણભૂત અને ભરોસાપાત્ર રીત છે, હાથે લખેલી નાજુક તપાસો કરતાં ઘણી સારી.
Practical
Email ચકાસો, પછી JSON માં જવાબ આપો
<?php
$email = trim($_POST["email"] ?? "");
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
$response = ["ok" => true, "message" => "Registered: " . $email];
} else {
$response = ["ok" => false, "message" => "Invalid email"];
}
// Turn the PHP associative array into a JSON string:
header("Content-Type: application/json");
echo json_encode($response);
// -> {"ok":true,"message":"Registered: riya@x.com"}
?>
Theory
json_encode અને json_decode
PHP JavaScript ના front-ends (BCA405-01) અને APIs સાથે JSON થી જ વાત કરે છે. બે functions એમની વચ્ચે પુલ બાંધે છે:
- json_encode($data): PHP નું array કે object JSON ના string માં ફેરવે છે. Associative array JSON નું object
{}બને છે; indexed array JSON નું array[]બને છે - json_decode($string): JSON ના string ને PHP માં ફેરવે છે. મૂળભૂત રીતે તમને object મળે છે; બીજા argument તરીકે
trueમોકલો (json_decode($s, true)) એટલે એને બદલે associative array મળે છે
એટલે portal પોતાનું registration નું record browser ને મોકલવા json_encode કરી શકે છે, અને અંદર આવતા JSON ને પ્રક્રિયામાં લેવા json_decode કરી શકે છે. Encode અને decode ની જોડી, સાથે associative array સામે object નો મેળ, પરીક્ષામાં JSON નો મુખ્ય સવાલ છે.
Quiz
Portal browser માં JavaScript થી email ચકાસે છે. તો પણ filter_var સાથે server બાજુની ચકાસણી શા માટે જરૂરી છે?
- જરૂરી નથી; client બાજુની JavaScript ની ચકાસણી પૂરતી છે
- Client બાજુની તપાસ ટાળી શકાય છે (JS બંધ કરીને, કે હાથે ઘડેલા requests થી), એટલે ખરી ચોકી તરીકે server એ પણ ચકાસવું જ પડે
- filter_var JavaScript કરતાં વધુ ઝડપી છે
- Server બાજુની ચકાસણી client બાજુની કોઈ પણ તપાસની જરૂર જ મિટાવી દે છે
Show the answer
Client બાજુની તપાસ ટાળી શકાય છે (JS બંધ કરીને, કે હાથે ઘડેલા requests થી), એટલે ખરી ચોકી તરીકે server એ પણ ચકાસવું જ પડે
Client બાજુની ચકાસણી વપરાશની સગવડ છે: એ ઝડપી પ્રતિભાવ આપે છે, પણ એ વપરાશકારના machine પર ચાલે છે અને એને હંમેશા ટાળી શકાય છે (JavaScript બંધ કરીને, કે form ને છોડીને સીધો request મોકલીને). એટલે ખરી સલામતીની સીમા તરીકે SERVER એ દરેક input ચકાસવો જ પડે, અને એ માટે filter_var એ PHP નું ભરોસાપાત્ર ઓજાર છે. વિકલ્પ A એવો જોખમી ભ્રમ છે જેને લીધે ખરેખર સલામતી તૂટે છે. વિકલ્પ C મુદ્દો ચૂકી જાય છે (સલામતીના કારણ સાથે ઝડપને લેવાદેવા નથી). વિકલ્પ D અતિશયોક્તિ છે: વપરાશના અનુભવ માટે client બાજુની તપાસ રાખવા જેવી છે, પણ એ server બાજુની ચકાસણીની જગ્યા કદી લેતી નથી. નિયમ: ઝડપ માટે client પર ચકાસો, સલામતી માટે server પર.
Think first
json_decode માંથી object કે array?
તમે event ના data નો અંદર આવતો JSON string json_decode કરો છો અને એને $data['seats'] ની જેમ વાપરવા માગો છો. json_decode ને શું મોકલવું પડે, અને ભૂલી જાઓ તો શું થાય? વિચારીને પછી tap કરો.
Show the answer
બીજા argument તરીકે true મોકલો: json_decode($json, true) associative array પાછું આપે છે, એટલે $data['seats'] ચાલે છે. true ભૂલી જાઓ તો json_decode મૂળભૂત રીતે object પાછું આપે છે, અને પછી તમારે object વાળી syntax વાપરવી પડે: $data->seats. Object પર $data['seats'] (કે array પર $data->seats) વાપરવાથી નિષ્ફળતા મળશે. એટલે બીજો argument જ ઘાટ નક્કી કરે છે: json_decode($s) object આપે છે (તીરવાળી પહોંચ), json_decode($s, true) associative array આપે છે (કૌંસવાળી પહોંચ). તમારો બાકીનો code data ને જે રીતે વાંચે છે એની સાથે બંધબેસતું એક પસંદ કરો, અને સુસંગત રહો. Associative array સામે object ની આ પસંદગી ખરા કામમાં અને પરીક્ષામાં વારંવાર ઠોકર ખવડાવે છે.
Watch out
Forms, filters અને JSON ના ફાંદા
Client ની ચકાસણી પર ભરોસો કરવો: server પર filter_var થી હંમેશા ફરી ચકાસો.
json_decode માં true ભૂલી જવું: મૂળભૂત રીતે object મળે છે (તીરવાળી પહોંચ), array નહીં (કૌંસવાળી પહોંચ).
filter_var boolean આપે છે એમ માની લેવું: FILTER_VALIDATE_EMAIL કિંમત (સાચી ગણાય એવી) કે false આપે છે; એને === true સાથે ન સરખાવો.
Content-Type: application/json ન ગોઠવવું: front-ends response ને ખોટી રીતે વાંચી શકે છે.
Decode થયેલું JSON કાચું જ HTML માં છાપવું: બતાવતાં પહેલાં તો પણ સફાઈ કરો (XSS).
Theory
ચકાસાયેલો input, વહેંચાયેલો ઘાટ: હવે યાદશક્તિ
Portal બરાબર ચકાસે છે અને JSON બોલે છે. પણ page load થાય એ ક્ષણે એ કોણ log in થયેલું છે તે હજી ભૂલી જાય છે: નવા page પર click કરો એટલે તમે ફરી અજાણી વ્યક્તિ. વેબ મૂળભૂત રીતે stateless છે, અને એ સુધારવું એ પછીના પાઠનું કામ છે: log in થયેલા વપરાશકારને pages વચ્ચે યાદ રાખવા COOKIES અને SESSIONS, સાથે ખાતરીનું EMAIL મોકલવું. Pages ના ઢગલાને ખરેખરના log in થયેલા અનુભવમાં આ જ ફેરવે છે.
Summary
Key takeaways
- Server બાજુની ચકાસણી ફરજિયાત છે: client બાજુની (JavaScript ની) તપાસ ટાળી શકાય છે અને એ ફક્ત વપરાશની સગવડ છે.
- filter_var($value, FILTER_VALIDATE_EMAIL/INT/URL) ચકાસે છે (કિંમત કે false આપે છે); FILTER_SANITIZE_* સાફ કરે છે.
- json_encode PHP ના data ને JSON ના string માં ફેરવે છે; associative arrays JSON નાં objects {} બને છે, indexed arrays JSON નાં arrays [] બને છે.
- json_decode JSON ને PHP માં ફેરવે છે: મૂળભૂત રીતે object મળે છે (તીરવાળી પહોંચ); associative array માટે true મોકલો (કૌંસવાળી પહોંચ).
- Front-end ને JSON પાછું આપો ત્યારે Content-Type: application/json ગોઠવો.
- આ એ જ JSON છે જેને તમે BCA405-01 માં મળ્યા હતા, હવે server બાજુ બનતું અને વંચાતું.
- યાદ રાખવાની કડી: તપાસવા filter_var, બહાર મોકલવા json_encode, અને array માટે json_decode(...,true).