Creating a login-less system

I’m developing a product quotation system, and in order to encourage Suppliers to submit a quote it is being designed so that no login is required.

The quote table is as follows:

id

product_id

supplier_id

price

verify

If a supplier is invited to quote, a record is created for them in the Quote table. The record when created has a random 10 digit/character string and in order to access the record the URL query string must contain the record ID and the random string. For example:

mysite/admin/quote/submit/id/6/verify/df4151ds5d


$this->_model=Quote::model()->findByPk($_GET['id'], 'verify=:verify', array(':verify'=>$_GET['verify']));

  1. How ‘secure’ is a system like this? Any additonal measures that could be applied?

  2. Is there any danger in exposing record ID values in the URL?

Record ID value is visible on update/view actions… it’s not a security problem per se…

It all depends on the algorithm to calculate the random string… maybe to incorporate some checking… for example the last digit/char is calculated from previous 9 with your proprietary formula… so that is more difficult to guess the random string…

Cool. Is it also possible to put that find query in an accessRule?

So something like:


array('allow',

	'actions'=>array('create', 'update'),

	'users'=>myFindMethod(),

),

haven’t tried it… and I’m not sure how would that affect overal speed… because myFindMethod() would return all the random strings so it could be a very big list…

I would put that check in a private function checkQuoteRandomString(id,qstring) that checks if the random strings correspond to the ID and returns true or false… and from actionCreate() and actionUpdate() call that function

On second thought…

you can do something like this




            array('allow',

                'actions'=>array('create,update'),

                'users'=>array('*'),

                'expression'=>'checkQuoteRandomString()',

            ),



and in checkQuoteRandomString() get the ID and querystring from $_GET and check if the string corresponds to the ID and return true or false…

What if you just do something like:


$this->_model=Quote::model()->find(

'quote_ref=:quote_ref AND user_id=:user_id',

array(':quote_ref'=>$_GET['quote_ref'], ':user_id'=>Yii::app()->user->id));

in the loadModel function? So if I run loadModel at the beginning of the action and it returns null then it would throw the exception.

So that would effectivly mean I don’t have to do anything in accessRules. Or am I missing something here?