414 URI too long. But not always
Instead of base64_encode()
ing the information you need to reset a password, with all the information there for everyone to base64_decode()
it, see this:
// this is from your example$encoded = 'eyJ0b2tlbiI6IiQyeSQxMCRMTlgzU29HdEdOaExsay5yQ1puQ2ZlZ1wvbVNcL09BMDV2SjhcL1wvcHNRNjZaQmRpbWpOdnhGQlciLCJ0aW1lIjoiMjAxNS0xMi0xMVQwOTozOToyOSswMTAwIiwiZW1haWwiOiJsb3JlbS51dC5hbGlxdWFtQGZldWdpYXRwbGFjZXJhdHZlbGl0Lm9yZyJ9';$data = json_decode( base64_decode($encoded), true);// array (// 'token' => '$2y$10$LNX3SoGtGNhLlk.rCZnCfeg/mS/OA05vJ8//psQ66ZBdimjNvxFBW',// 'time' => '2015-12-11T09:39:29+0100',// 'email' => 'lorem.ut.aliquam@feugiatplaceratvelit.org',// )
Persist data in a table
How about instead persisting that data - either in a database or elsewhere with limited lifetime - and then either using a UUID or a hash created with that data above as an identifier for the password reset?
CREATE TABLE `password_reset` ( `id` char(40) NOT NULL DEFAULT '', `token` char(60) NOT NULL DEFAULT '', `time` datetime NOT NULL, `email` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Identifier from SHA-1
Then generate your identifier:
$id = sha1(serialize([ 'token' => '$2y$10$LNX3SoGtGNhLlk.rCZnCfeg/mS/OA05vJ8//psQ66ZBdimjNvxFBW', 'time' => '2015-12-11T09:39:29+0100', 'email' => 'lorem.ut.aliquam@feugiatplaceratvelit.org', 'foo' => microtime(), // for some variation]);
Store the data in your table, and there your have your fixed length identifier, and your password reset URL becomes
http://example.com/resetPassword/0f4d2541c25ba8edbb3cd6df362d7dbf6317d7a5
Identifier as UUID
Instead of using sha1()
to create a hash from some input, it would probably be better to use, for example, ramsey/uuid
to generate a time-based UUID (fixed length, 36 characters):
use Ramsey\Uuid\Uuid;$id = Uuid::uuid1()->toString()
While this doesn't solve your problem of allowing really long URIs, it solves the problem in a better, much safer way.
Bonus
Have a look at OWASP's Forgot Password Cheatsheet and related, maybe it helps in making your application more secure!
Use POST method instead of get and it will resolve your problem.
But if you still would like to use "GET" method instead of "POST" method, then under Apache, value of LimitRequestLine
can be changed to something larger than its default of 8190 if you want to support a longer request URI.
If you can't find LimitRequestLine
into apache config file, just add the line yourself anywhere you like. e.g: LimitRequestLine 100000
However, note that if you're actually running into this limit, you are probably abusing GET to begin with. You should use POST to transmit this sort of data -- especially since you even concede that you're using it to update values
There are at least 2 config variables that can cause 414 error.
LimitRequestLine directive allows the server administrator to set the limit on the allowed size of a client's HTTP request-line. By default it is 4094.
LimitRequestFieldSize directive allows the server administrator to set the limit on the allowed size of an HTTP request header field. By default it is 4094 bytes
Try increase both of them or try to see how big is request that comes to server. It could be useful if you put here the request that you send to server.
Useful links:
- https://confluence.atlassian.com/display/JIRAKB/Long+URLs+Are+Rejected+by+Apache+with+'Request-URI+Too+Large'+Error
- http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestline
- http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestfieldsize
- How do I resolve a HTTP 414 "Request URI too long" error?