原始文章(我的部落格):
http://blog.tuzaiz.id...hives/26大家都知道,许多服务网站都一定会有一个用户系统,供用户注册、登入、登出,这也成为私人保护的第一道门户!
那一个会员系统又该要如何去作设计呢?其实用户系统是一个很简单的概念,如上面所写,主要就是注册、登入、登出三种功能,而这三个功能细分的话就会如下面:
注册
1. 输入表单 → 2. 资料检查(帐号重叠、输入内容与安全性) → 3. 存入资料库
登入
1. 登入表单 → 2. 检查帐号密码 → 3. 比对正确则登记登入
登出
1. 注销登入资料与所有变数!
其实这几项的概念都相当简洁,但是这也是整个网站的第一步,因此虽然简单却要最严谨去设计,包括安全与漏洞都要小心谨慎!
在做任何网站之前,最重要的事情就是先做好规划,切忌边做边想边修改,这样不但会让自己的逻辑混乱,也会让自己的程式弄的相当乱,难以修改!
设计资料库
在写程式之前,先将我们规划好需要用到的资料设计成资料库,这边我使用MySQL,一个简单的用户系统大概只要一个到两个的资料表就好,养成习惯尽量不要让资料库弄的太过复杂,多多利用MySQL的关联资料库功能!
这边假设我想要制作两个资料表,一个存放帐号资料(user)另一个存放个人资料(personal)
帐号资料
资料表名称: user
* 资料表栏位: user_id (这设为主键,使用数字格式(INT),并且依照使用习惯使用自动递增,作为每个帐号独立的ID)
* user_name (使用者名称,使用字串格式(VARCHAR),长度依自己选择大约在20左右即可)
* user_pass (使用者密码,也使用字串格式(VARCHAR),为了安全我使用MD5编码所以长度设大一点,约100即可
个人资料
资料表名称:personal
* 资料表栏位: user_id (作为与帐号资料的关联,由于一个帐号只会有一个个人资料,因此可以以此为主键或是另外增加一个person_id作主键而user_id作索引键都可以)
* person_name (个人姓名,依自己设计的资料内容作设计,使用字串VARCHAR,长度20)
* person_birth (个人生日,可选择用字串储存或是DATE储存,内容格式不同,下面会作解释)
* 其他资料可依照网站需求来作设计
注册会员
第一步:显示表单
这应该不用太做说明,就依照自己资料库的设计来作HTML表单而已!以我的设计来说就是一个帐号、两个密码(避免输入错误用)
第二步:验证输入资料
这一步很重要,不但要注意是不是有输入资料,还要注意资料内容格式对不对,最重要的就是要注意是不是有人可以利用输入资料来破坏你的资料库(这是一个很明显的问题,下面我会稍微解释一下)!
网页设计师有一句流传下来的话,就是永远不要相信使用者输入的资料,千万不要用自己的逻辑去判断别人不会这样作,一定要避免掉所有可能会造成破坏的问题!
所谓利用表单来破坏资料库,就是人家在字串输入的表单中输入的内容会导致资料库的修改或破坏,下面作个假设
我设计一个表单送出后会将输入资料送出到MySQL中存放,PHP操纵MySQL的方式都是依靠SQL指令来进行,假设我有一个表单是送出后要插入到资料库中,那我会用下面那个SQL来操作
1. INSERT INTO `database` (`name`) VALUES ('{$value}');
database是资料表名称
`name` 是栏位名称
$value 是输入表单内容存放的变数
假设我输入的资料是1 那这个SQL就会是
1. INSERT INTO `database` (`name`) VALUES (Ƈ');
这样程式就会很正常的输入1这个数值到资料库中存放,可是这是理论上,如果使用者不输入一般文字,而输入像下面这样
1. '); DELETE FROM `database`; INSERT INTO `databse` (`name`) VALUES ('
这样子如果我们不避免掉的话,就会变成
1. INSERT INTO `database` (`name`) VALUES (''); DELETE FROM `database`; INSERT INTO `databse` (`name`) VALUES ('');
也就是可以将资料库中所有资料全部删除掉!记住,不要相信自己的理论,不要认为使用者不会知道你的资料库名称,或是使用者不会这样作,有这点风险我们都要避免!
还有另一种危险就是要小心使用者输入HTML码来破坏整个网站的版面!
这只要使用htmlspecialchars() 这个函式就可以跳脱HTML码
1. $value = htmlspecialchars($value);
使用者帐号:
帐号方面要注意,首先是你的帐号是否愿意支援中文,长度要在多少(要避免超过资料库设计时的上限),注意SQL安全问题
一般来说是建议不要使用中文来当作使用者帐号,因为中文在程式中与英文结构不同,在BIG5的格式中PHP会对几个字(许功盖)造成错误问题,而现在虽然MySQL已经支援了多语系且可以使用Unicode,但是还是建议尽量使用英文字母、底线与数字来作为帐号!
长度我们也要注意,一般最好是4个字以上15个字以下,如果支援中文要记得中文一个字代表两个字元!这边检查最好使用正规表达式来作检测!
1. ereg("^[a-zA-Z0-9_]{4,15}$", $user_name);
这样就只能接受由数字、英文与底线所组成的4~15个字元的内容!
接下来就是最最重要的,就是注意使用者帐号千万不能跟其他人的重叠,所以要先检查是不是有这个使用者名称存在喔!
使用者密码:
密码除了上面的SQL安全与长度之外,还要注意密码能够输入的字元,现在为了密码的安全,一般我们会建议使用者在密码的设计上尽量要更加的安全,所谓的安全密码大概有下面几条规则
* 不可由数字开头
* 需包含数字、英文字母大写、英文字母小写、符号其中三种来作组合
* 符号使用半形可直接输入的符号,并且避免用引号(’ “)
因为这样,所以除了要避免SQL安全之外,我们还要针对一些可能会造成程式判断错误的符号进行跳脱(如; ‘ ” \ NULL ),这问题很好解决,只要在密码的变数使用addslashes这个函式就可以了
1. $user_pass = addslashes($user_pass);
一样,密码我们用正规表达式来判断输入是否正确
我习惯加上了一行 $user_pass = md5($user_pass); ,这是将密码使用md5加密过后再放进资料库中的作法,这样一来人家经由资料库或传输封包获取你的密码的可能性就大大降低,缺点是你的密码遗失的话站长也无法帮你取得你的密码,不过可以请站长重新帮你设定新的密码,这种作法在各大网站中常常可以见到!
验证过程如果有错误,那就显示错误然后将网页跳回前页,资料验证没有错误的话,接着就只要将这些输入的资料送进资料库中存放就好!
使用者登入
登入系统也很简单,主要就是使用SQL去查询资料库中是不是有这笔帐号密码相同的资料,如果有就将登入资讯以SESSION或Cookie的方式暂存在电脑中,注意不要将重要资料如密码放置于Cookie或SESSION中,因为这些会在电脑中留下纪录,如果在公用电脑中上网难保人家会不会偷取的你的资料,我的习惯是只存放一个用户ID和确认码,其他资料则经过这个ID去资料库中取得就好!
登入验证
登入表单送出后,当然也要经过验证动作,SQL安全当然是不用说得,而搜索的SQL就用SELECT
1. SELECT * FROM `user` WHERE `user_name`='{$user_name}' AND `user_pass`='{$user_pass}'
取出有相同帐号与密码的资料,有资料就代表正确,没有资料就是帐号密码不存在或错误!
登入动作
我的习惯是将登入资料以Session方式保存,只保存在一个浏览器进程,关掉浏览器后过一段时间就需要重新登入才可以使用,虽然麻烦可是可以避免使用公共电脑的危险!
登入成功后我就将用户ID放入Session中,并且设计演算一个确认码同时放入Session中,以免人家假造Session,这确认码的演算方式不能够让其他人知道,也可以利用md5加密编码!
以后网页只要读取看看Session存不存在,确认码与用户ID是否配合,就可以判断是否已经登入过!
登出
登出更简单,只要将Session的变数都移除掉,并拿掉一切个人资料的存放,虽然简单但是却要小心谨慎,避免任何资料残留的可能!
一个简单的会员系统就是这样写出来的,概念很简单却要小心谨慎,对于初学者来说,这无非是最好的练习作品,这也是学习资料库的第一步!