Generates (or regenerates) a cryptographically-secure token to be used for the life of the
client session, and stores the token using the Session class.
public static get ( array $options = [] ) : string | ||
$options | array | An array of options to be used when generating or storing the token: - `'regenerate'` _boolean_: If `true`, will force the regeneration of a the token, even if one is already available in the session. Defaults to `false`. - `'sessionKey'` _string_: The key used for session storage and retrieval. Defaults to `'security.token'`. - `'salt'` _string_: If the token is being generated (or regenerated), sets a custom salt value to be used by `String::hash()`. - `'type'` _string_: The hashing algorithm used by `String::hash()` when generating the token. Defaults to `'sha512'`. |
return | string | Returns a cryptographically-secure client session token. |
/** * 初始化CSRF并检查token是否存在, 不存在则生成token */ public static function init() { $value = \lithium\storage\Session::read(self::$_session_key); if (empty($value)) { RequestToken::get(); } }
/** * Tests that a random sequence of keys and tokens properly match one another. */ public function testKeyMatching() { for ($i = 0; $i < 4; $i++) { $token = RequestToken::get(array('regenerate' => true)); for ($j = 0; $j < 4; $j++) { $key = Password::hash($token); $this->assertTrue(RequestToken::check($key)); } } }
/** * Allows a user to update their own profile. * */ public function update() { if (!$this->request->user) { FlashMessage::write('You must be logged in to do that.', 'default'); return $this->redirect('/'); } // Special rules for user creation (includes unique e-mail) $rules = array('email' => array(array('notEmpty', 'message' => 'E-mail cannot be empty.'), array('email', 'message' => 'E-mail is not valid.'), array('uniqueEmail', 'message' => 'Sorry, this e-mail address is already registered.'))); // Get the document from the db to edit $conditions = array('_id' => $this->request->user['_id']); $document = User::find('first', array('conditions' => $conditions)); $existingProfilePic = !empty($document->profilePicture) ? $document->profilePicture : false; // Redirect if invalid user...This should not be possible. if (empty($document)) { FlashMessage::write('You must be logged in to do that.', 'default'); return $this->redirect('/'); } // If data was passed, set some more data and save if ($this->request->data) { // CSRF if (!RequestToken::check($this->request)) { RequestToken::get(array('regenerate' => true)); } else { $now = new MongoDate(); $this->request->data['modified'] = $now; // Add validation rules for the password IF the password and password_confirm field were passed if (isset($this->request->data['password']) && isset($this->request->data['passwordConfirm']) && (!empty($this->request->data['password']) && !empty($this->request->data['passwordConfirm']))) { $rules['password'] = array(array('notEmpty', 'message' => 'Password cannot be empty.'), array('notEmptyHash', 'message' => 'Password cannot be empty.'), array('moreThanFive', 'message' => 'Password must be at least 6 characters long.')); // ...and of course hash the password $this->request->data['password'] = Password::hash($this->request->data['password']); } else { // Otherwise, set the password to the current password. $this->request->data['password'] = $document->password; } // Ensure the unique e-mail validation rule doesn't get in the way when editing users // So if the user being edited has the same e-mail address as the POST data... // Change the e-mail validation rules if (isset($this->request->data['email']) && $this->request->data['email'] == $document->email) { $rules['email'] = array(array('notEmpty', 'message' => 'E-mail cannot be empty.'), array('email', 'message' => 'E-mail is not valid.')); } // Set the pretty URL that gets used by a lot of front-end actions. // Pass the document _id so that it doesn't change the pretty URL on an update. $this->request->data['url'] = $this->_generateUrl($document->_id); // Do not let roles or user active status to be adjusted via this method. if (isset($this->request->data['role'])) { unset($this->request->data['role']); } if (isset($this->request->data['active'])) { unset($this->request->data['active']); } // Profile Picture if (isset($this->request->data['profilePicture']['error']) && $this->request->data['profilePicture']['error'] == UPLOAD_ERR_OK) { $rules['profilePicture'] = array(array('notTooLarge', 'message' => 'Profile picture cannot be larger than 250px in either dimension.'), array('invalidFileType', 'message' => 'Profile picture must be a jpg, png, or gif image.')); list($width, $height) = getimagesize($this->request->data['profilePicture']['tmp_name']); // Check file dimensions first. // TODO: Maybe make this configurable. if ($width > 250 || $height > 250) { $this->request->data['profilePicture'] = 'TOO_LARGE.jpg'; } else { // Save file to gridFS $ext = substr(strrchr($this->request->data['profilePicture']['name'], '.'), 1); switch (strtolower($ext)) { case 'jpg': case 'jpeg': case 'png': case 'gif': case 'png': $gridFile = Asset::create(array('file' => $this->request->data['profilePicture']['tmp_name'], 'filename' => (string) uniqid(php_uname('n') . '.') . '.' . $ext, 'fileExt' => $ext)); $gridFile->save(); break; default: $this->request->data['profilePicture'] = 'INVALID_FILE_TYPE.jpg'; //exit(); break; } // If file saved, set the field to associate it (and remove the old one - gotta keep it clean). if (isset($gridFile) && $gridFile->_id) { if ($existingProfilePic && substr($existingProfilePic, 0, 4) != 'http') { $existingProfilePicId = substr($existingProfilePic, 0, -strlen(strrchr($existingProfilePic, '.'))); // Once last check...This REALLY can't be empty, otherwise it would remove ALL assets! if (!empty($existingProfilePicId)) { Asset::remove(array('_id' => $existingProfilePicId)); } } // TODO: Maybe allow saving to disk or S3 or CloudFiles or something. Maybe. $this->request->data['profilePicture'] = (string) $gridFile->_id . '.' . $ext; } else { if ($this->request->data['profilePicture'] != 'INVALID_FILE_TYPE.jpg') { $this->request->data['profilePicture'] = null; } } } } else { $this->request->data['profilePicture'] = null; } // Save if ($document->save($this->request->data, array('validate' => $rules))) { FlashMessage::write('You have successfully updated your user settings.', 'default'); $this->redirect(array('library' => 'li3b_users', 'controller' => 'users', 'action' => 'update')); } else { $this->request->data['password'] = ''; FlashMessage::write('There was an error trying to update your user settings, please try again.', 'default'); } } } $this->set(compact('document')); }