通过自定义Module实现URl重写和登陆验证
- 格式:doc
- 大小:112.00 KB
- 文档页数:5
djangoModel层常⽤验证器及⾃定义验证器详解在Django中,对数据进⾏校验有两种⽅式:⼀种是通过Form校验,⼀种是通过Model校验。
在此,我对Model中的校验⽅法做下记录。
⽰例之前补充以下⼏点:1、Django数据校验⽅式分为以下三步:Model.clean_fields() 验证字段基本规则⽐如长度格式等;Model.clean() 可⾃定义验证条件和报错信息;Model.validate_unique() 为验证添加的唯⼀性约束。
2、此三步验证通过调⽤full_claen(exclude=None, validate_unique=True)来依次执⾏。
exclude:可以⽤来指定不需要执⾏校验的field。
ModelForm也利⽤这个参数来将field排除。
validate_unique:⽤来指定是否需要执⾏Model.validate_unique()。
3、⽽full_clean()⼜是通过调⽤is_valid()⽅法来执⾏。
4、save()执⾏的时候是不会⾃动调⽤full_clean()来进⾏校验的。
校验应该在save()执⾏之前完成,你可以先在form进⾏校验,也可以在model中进⾏校验。
但是,你必须确保通过这两个校验之后的数据是绝对没有问题的“⼲净”数据,然后再调⽤save()⽅法将数据存储⼊库。
5、校验中的错误处理我们使⽤ValidationError来在Model.clean中抛出错误,这个错误信息将会存储在以NON_FIELD_ERRORS为key的字典中。
这个key是⽤来存储对于整个model中的错误信息的。
如何获取校验的错误信息:from django.core.exceptions import ValidationError, NON_FIELD_ERRORStry:article.full_clean()except ValidationError as e:non_field_errors = e.message_dict[NON_FIELD_ERRORS]如何指定对于某个特定的field的校验错误信息:class Article(models.Model):...def clean(self):if self.status == 'draft' and self.pub_date is not None:# raise ValidationError({'pub_date': _('Draft entries may not have a publication date.')})raise ValidationError({'pub_date': 'Draft entries may not have a publication date.'})...如何指定多个field的校验错误信息:class Article(models.Model):...def clean(self):if self.status == 'draft' and self.pub_date is not None:raise ValidationError({'pub_date': 'Draft entries may not have a publication date.','creator': 'Creator can't be null'})...如何指定全局性校验错误信息:class Article(models.Model):...def clean(self):if self.status == 'draft' and self.pub_date is not None:raise ValidationError('Draft entries may not have a publication date.')...进⼊正题:⼀、如何使⽤验证器:在验证某个字段的时候,在模型或者⾃定义form表单中传递⼀个 validators 参数⽤来指定验证器,进⼀步对数据进⾏过滤。
Laravel 入口文件 Rewrite 写法一、背景介绍1. Laravel 是一款优秀的 PHP 开发框架,为开发者提供了丰富的工具和功能,使得开发过程更加高效、快捷。
2. 在使用 Laravel 进行开发时,我们经常需要对项目的 URL 进行重写(rewrite),以实现更加友好的 URL 结构。
本文将重点介绍在Laravel 中如何进行入口文件的 rewrite 写法。
二、入口文件 Rewrite 的作用1. 隐藏入口文件:通过 rewrite,我们可以隐藏 Laravel 项目的入口文件(如 index.php),使得用户在访问全球信息站时无需在 URL 中显示入口文件,提高了全球信息站的美观性和安全性。
2. 实现 URL 路由:通过 rewrite,我们可以实现自定义的 URL 路由,将复杂的 URL 转化为简洁明了的形式,提高用户体验。
三、Apache 服务器下的入口文件 Rewrite1. 在 Apache 服务器上,我们可以通过修改 .htaccess 文件来实现入口文件的 rewrite。
2. 我们需要确保服务器已经开启了 mod_rewrite 模块。
然后在项目的 public 目录下创建 .htaccess 文件。
3. 在 .htaccess 文件中,我们可以使用以下代码来实现入口文件的rewrite:```<IfModule mod_rewrite.c><IfModule mod_negotiation.c>Options -MultiViews</IfModule>RewriteEngine OnRewriteCond {REQUEST_FILENAME} -d [OR]RewriteCond {REQUEST_FILENAME} -fRewriteRule ^ ^$1 [N]RewriteCond {REQUEST_URI} (\.\w+$) [NC]RewriteRule ^(.*)$ public/$1RewriteCond {REQUEST_FILENAME} !-dRewriteCond {REQUEST_FILENAME} !-fRewriteRule ^ server.php</IfModule>```四、Nginx 服务器下的入口文件 Rewrite1. 在 Nginx 服务器上,我们可以通过修改配置文件来实现入口文件的 rewrite。
在Django中,⾃定义User模型,使⽤token鉴权,实现注册、登录、修改密码等API在Django中,⾃定义User模型,实现注册、登录、修改密码、登出、⾸页5个API。
⼤体步骤是:⾃定义User模型->重构鉴权后台->settings设置->views修改->Postman测试。
1、在models.py中,仿照Django官⽹提供的样例,⾃定义User模型,主要是增加了phone这个必选字段。
代码如下:from django.db import modelsfrom django.contrib.auth.models import ( BaseUserManager, AbstractBaseUser)class CustomUserManager(BaseUserManager):def create_user(self, user_id, phone, email=None, password=None):"""Creates and saves a User with the given phone,...."""if not phone:raise ValueError('phone must be given when create user')if email:email = self.normalize_email(email)user = self.model(user_id = user_id,phone = phone,email = email,)user.set_password(password)user.save(using=self._db)return userdef create_superuser(self, user_id, phone=None, email=None, password=None):user = self.create_user(user_id,phone=phone,email=email,password=password,)user.is_admin = Trueuser.save(using=self._db)return userclass CustomUser(AbstractBaseUser):user_id = models.CharField(max_length=30,unique=True,)phone = models.CharField(max_length=30,null=True,blank=True,unique=True,default=None,)email = models.EmailField(verbose_name='email address',max_length=255,unique=True,null=True,blank=True,)is_active = models.BooleanField(default=True)is_admin = models.BooleanField(default=False)objects = CustomUserManager()USERNAME_FIELD = 'user_id'REQUIRED_FIELDS = ['phone']def __str__(self):return er_iddef has_perm(self, perm, obj=None):"Does the user have a specific permission?"# Simplest possible answer: Yes, alwaysreturn Truedef has_module_perms(self, app_label):"Does the user have permissions to view the app `app_label`?"# Simplest possible answer: Yes, alwaysreturn True@propertydef is_staff(self):"Is the user a member of staff?"# Simplest possible answer: All admins are staffreturn self.is_admin # 是admin的话,就是雇员2、在app⽬录下,新建backends.py⽂件,仿照Django官⽹提供的样例(还是上⾯给出的⽹址),写出⾃定义的CustomBackend(⾃定义的鉴权后台):from .models import CustomUser as Userclass CustomBackend:def authenticate(self,request,user_id=None,phone=None,password=None,**kwargs):# ⽀持后台登录功能,因为admin登录提交的时候会发送username字段if user_id is None:user_id = kwargs.get('username')try:if phone:user = User.objects.get(phone=phone)elif user_id:user = User.objects.get(user_id=user_id)if user.check_password(password):return userexcept User.DoesNotExist:return Nonereturn Nonedef get_user(self, user_id):try:return User.objects.get(pk=user_id)except User.DoesNotExist:return None3、在settings中设置:(1)要使⽤⾃定义的User模型和鉴权后台:# Custom UserAUTH_USER_MODEL = 'chat_user.CustomUser'# Custom Authentication backendAUTHENTICATION_BACKENDS = ['chat_user.backends.CustomBackend'](2)确定使⽤token鉴权:INSTALLED_APPS = [......'rest_framework','rest_framework.authtoken','chat_user',] 4、修改views.py,实现注册、登录、修改密码、登出、⾸页5个API(前4个是post⽅式,最后⼀个是get⽅式):import uuidfrom django.shortcuts import renderfrom django.contrib import authfrom rest_framework import statusfrom rest_framework.response import Responsefrom rest_framework.views import APIViewfrom rest_framework.authentication import BasicAuthentication,SessionAuthentication,TokenAuthenticationfrom rest_framework.authtoken.models import Tokenfrom rest_framework.permissions import AllowAny,IsAuthenticatedfrom .models import CustomUser as Userclass Register(APIView):def post(self, request):"""注册"""phone = request.data.get('phone')password = request.data.get('password')user_id = uuid.uuid4().hexuser = User.objects.create_user(user_id=user_id, phone=phone, password=password)user.save()context = {"status": status.HTTP_200_OK,"msg": "⽤户注册成功"}return Response(context)class Login(APIView):authentication_classes = (BasicAuthentication,TokenAuthentication) # 使⽤基础的和token的验证⽅式 permission_classes = (AllowAny,) # 允许所有⼈访问def post(self, request):"""登录"""phone = request.data.get('phone')password = request.data.get('password')user = auth.authenticate(request, phone=phone, password=password)if user:auth.login(request, user)token = Token.objects.create(user=user)context = {"status": status.HTTP_200_OK,"msg": "⽤户登录成功","user_id":er_id,"token":token.key,}else:context = {"status": status.HTTP_403_FORBIDDEN,"msg": "⽤户名或密码错误",}return Response(context)class Logout(APIView):authentication_classes = (BasicAuthentication,TokenAuthentication)permission_classes = (IsAuthenticated,)def post(self, request):"""登出"""#auth.logout(request)Token.objects.filter(user=er).delete()context = {"status": status.HTTP_200_OK,"msg": "退出成功"}return Response(context)class Password(APIView):authentication_classes = (BasicAuthentication,TokenAuthentication) # 使⽤基础的和token的验证⽅式 permission_classes = (IsAuthenticated,) # 只允许所有通过鉴权的⼈访问def post(self, request):"""修改密码"""new_password1 = request.data.get('new_password1')new_password2 = request.data.get('new_password2')if new_password1 and new_password1 == new_password2:er.set_password(new_password1)er.save()context = {"status": status.HTTP_200_OK,"msg": "修改密码成功"}else:context = {"status": status.HTTP_403_FORBIDDEN,"msg": "两次密码不⼀样或没密码"}return Response(context)class Index(APIView):authentication_classes = (BasicAuthentication,TokenAuthentication) # 使⽤基础的和token的验证⽅式permission_classes = (IsAuthenticated,) # 只允许所有通过鉴权的⼈访问def get(self,request):context = {"data":"Hello World!","status":200,"msg":"访问index成功"}return Response(context)5、确认urls已配置好,包括项⽬的urls和应⽤的urls,下⾯列出的仅是应⽤的urls:from django.urls import path, include, re_pathfrom . import viewsurlpatterns = [path('register/', views.Register.as_view()),path('login/', views.Login.as_view()),path('logout/', views.Logout.as_view()),path('password/', views.Password.as_view()),path('index/', views.Index.as_view()),]6、写⼊数据库:python manage.py makemigrationspython manage.py migrate在写⼊的时候可能会报错,django.db.utils.IntegrityError: UNIQUE constraint failed,是因为之前数据库中有user的数据,⽽表结构不⼀样,删除原来的⽤户数据再写⼊就⾏;我是删除了整个sqlite数据库,重新写⼊数据库。
URL重写规则开启mod_rewrite开启mod_rewrite模块使⽤URL重写功能,需要安装mod_rewrite模块。
使⽤phpinfo()函数,找到Apache Modules section部分,可以看到当前apache加载模块。
如果没有开启mod_rewrite, 就需要配置mod_rewrite.so的路径:LoadModule rewrite_module modules/mod_rewrite.soApache2内置了mod_rewirte,在配置虚拟主机的配置⽂件VirtualHost部分打开引擎:RewriteEngine on这句之后就可以使⽤重写语法了。
VirtualHost⽂件部分的Directory配置必须是:Options Includes FollowSymLinks #允许使⽤符号链接AllowOverride All #允许⽬录配置⽂件.htaccess。
如果不使⽤是AllowOverride None利⽤mod_rewrite重写URL主要使⽤两个基本的指令RewriteRule和RewriteCond。
⼀个最常⽤的正则就是(.*)。
它含有两个元素:⼀是“点”,表⽰任意字符;⼆是“星”,表⽰以前的全部字符。
所以(.*)会匹配{REQUEST_URI}的所有字符。
Rewrite重写引擎的输⼊串是 {REQUEST_URI},也就是URL中出去域名以及“?”符号后的所有查询字符。
重定向的URL中要提取出“USA/California/San_Diego”,匹配模式正则表达式的原型是:(.*)/(.*)/(.*)以上正则,在{REQUEST_URI}中通过两个“/”的分割存储了三个值,为了解决我们具体问题,我们得加⼀点限制――毕竟,第⼀个和最后⼀个原⼦可以匹配任何字符。
开始,我们可以添加⼀些特殊的字符,⽐如表⽰正则“开始”或者“结束”,“^”字符表⽰正则的开始⽽“”表⽰正则的结束。
使⽤重写url机制实现验证码换⼀张功能重写URL机制:为了保证⼀个url的地址唯⼀,可每次向服务器传递的参数不⼀样即可。
由数据请求的抱头信息可分析到:抱头信息包括http协议,IP地址,端⼝号,⼯程名,请求参数列表,要想访问的资源不发⽣变化,只能变化参数连表。
此处在实现验证码的换⼀张的功能时,就是利⽤了改变参数列表的值进⾏刷新。
详细代码实现:<%@page import="javax.imageio.ImageIO"%><%@page import="java.awt.Font"%><%@page import="java.awt.Color"%><%@page import="java.awt.Graphics"%><%@page import="java.awt.image.BufferedImage"%><%@ page contentType="image/jpeg" language="java" import="java.util.*" pageEncoding="UTF-8"%><%int w=100;int h=30;BufferedImage bi=new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);Graphics g=bi.getGraphics();Color c=g.getColor();Font f=g.getFont();Random r=new Random();Color bg=new Color(150+r.nextInt(100),150+r.nextInt(100),150+r.nextInt(100));g.setColor(bg);g.fillRect(0, 0, w, h);String code="";for(int i=1;i<=4;i++){int num=r.nextInt(10);code=code+num;Color num_c=new Color(r.nextInt(150),r.nextInt(150),r.nextInt(150));g.setColor(num_c);g.drawString(String.valueOf(num), 20*i, h/2);}request.getSession().setAttribute("code", code);//清空缓存response.setHeader("pragma", "bo-cache");response.setHeader("cache-control", "bo-cache");response.addDateHeader("expires", 0);ImageIO.write(bi, "jpeg", response.getOutputStream());out.close();%>添加登录页⾯:<%@ page contentType="text/html; charset=utf-8" language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><base href="<%=basePath%>" rel="external nofollow" ><title>My JSP 'login.jsp' starting page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0"><meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css" rel="external nofollow" >--><script type="text/javascript">function changeimage(){var d=new Date();//⽣成时间戳,document.getElementById("img").src="image.jsp?t="+d;//由变化的时间使参数连表发⽣变化,url重写}</script></head><body><font color="red">${requestScope.msg }</font><form action="loginServlet" method="post">name:<input type="text" name="uname"><br>pwd:<input type="pwd" name="upwd"><br>code:<input type="text" name="code" size="5"><img id="img" alt="" src="image.jsp "><a onclick="changeimage()">换⼀张</a><br><input type="submit" ></form></body></html>利⽤时间的变化,每次⽣成时间戳,传参给请求的url,达到重写url的⽬的,从⽽实现了换⼀张的刷新功能。
在这篇文章中,清源分享给大家一个php实现自动登录与自动验证的实现代码,有需要的朋友可以参考一下:代码:1.$urls = parse_url($db_bbsurl);2.$domain = $urls['host'];3.include_once (R_P .'require/admvclient.php');4.$adm_oem= new Cnzz_Adm_Oem();5.//判断config文件是否存在用户密码6.pwCache::getData(D_P . "data/bbscache/adm_config.php");//用户名密码配置文件7.if (isset($adm_user) && isset($adm_pwd)) {8.$request = array("adm_user"=>$adm_user,"adm_pwd"=>$adm_pwd,'cms'=>'pw');9.$token = $adm_oem->get_appkey_once($request);10.if ($token<0){11.if($token==-1){12.adminmsg('传递参数为空或传递参数非数字');13.}else if($token==-2){14.adminmsg('传递参数password错误');15.}16.}else{17.$apikey = $token['adm_key'];19.}else{20.$Key = md5($domain.'KclGiq7H');21.$request = array('cms'=>'pw','domain'=>$domain,'key'=>$Key);22.$token = $adm_oem->reg_user_once($request);23.if ($token<0){//异常24.if($token==-1){25.adminmsg('key有误');26.} else if($token==-2){27.adminmsg('域名长度有误(1~64)');28.} elseif($token==-3){29.adminmsg('域名输入有误(比如输入汉字)');30.} elseif($token==-4){31.adminmsg('域名插入数据库有误');32.} elseif($token==-5){33.adminmsg('IP用户调用页面超过阀值,阀值暂定为10');34.} (PS:T不错的PHP Q扣裙:276167802,验证:cz)35.} elseif (is_array($token) && isset($token)){36.$adm_user = $token['adm_user'];37.$adm_pwd = $token['adm_pwd'];38.$apikey = $token['adm_key'];39.pwCache::setData(D_P.'data/bbscache/adm_config.php',"<?phprn$adm_user=".$adm_user.";rn$adm_pwd=".$adm_pwd."rn?>");41.}者有所帮助,感谢阅读本文。
Url路径重写的原理的地址重写(URLRewriter)实现原理及代码⽰例吴剑 2007-01-01原创⽂章,转载必需注明出处:概述访问者输⼊:/default.aspx,实际请求和响应的地址却是:/wu-jian/default.aspx, 这就是UrlRewrite,除了实现⼆级域名功能,它在简化⽤户输⼊地址、SEO、⽹站版本迭代更新等多个⽅⾯发挥着重要作⽤。
微软曾在.net framework 1.1中提供过⼀个名为URLRewriter的⼩⼯具供开发⼈员轻松实现UrlRewrite,下载地址为:本⽂以URLRewriter为例,在.net framework 2.0的环境下做了⼩部分优化调整,供⼤家学习和参考,能⼒有限,不⾜之处请⼤家及时指出。
本⽂假设读者对URLRewriter、的 Http管线有⼀定了解,否则请查阅相关资料。
配置URLRewriter在web.config⾥通过⾃定义配置结合正则表达式来实现URL重写。
⾃定义节点的声明:<configSections><section name="RewriterConfig"type="PaoTiao.PTRewriter.Config.RewriterConfigSerializerSectionHandler, PaoTiao.PTRewriter"/></configSections>⾃定义节点配置项:<RewriterConfig><Rules><RewriterRule><LookFor>^http://([a-zA-Z0-9]{4,16})/default.aspx$</LookFor><SendTo>/$1/default.aspx</SendTo></RewriterRule><RewriterRule><LookFor>^/([a-zA-Z0-9]{4,16})/$</LookFor><SendTo>/test/url.aspx?p=$1</SendTo></RewriterRule></Rules></RewriterConfig>如上我配置了两个规则,以实例说明,第⼀个可将: 重写到:/wu-jian/default.aspx第⼆个可将:/wu-jian 重写到:/test/url.aspx?p=wu-jian但微软的URLRewriter LookFor并不⽀持到域名位置,它只能在根⽬录之后做⽂章,截选了它源码DEMO中的⼀段:<RewriterRule><LookFor>~/(\d{4})/(\d{2})/(\d{2})\.aspx</LookFor><SendTo>~/ShowBlogContent.aspx?year=$1&month=$2&day=$3</SendTo></RewriterRule>可以发现,当需要使⽤⼆级域名或⾃定义级别更⾼的rewrite时,URLRewriter是不⽀持的,所以在此我将源代码作了⼀⼩部分优化,匹配与重写都使⽤LookFor和SendTo中的原始表达式,不做任何智能替换与修改。
URLRewriteModule2.1URL重写模块规则写法⽬录先决条件设置测试⽹页创建重写规则命名规则定义模式定义动作查看配置⽂件中的重写规则测试重写规则创建重定向规则测试重定向规则创建访问阻⽌规则测试访问阻⽌规则概要先决条件本演练需要满⾜以下先决条件:IIS安装 URL Rewrite Module 2.1下载页⾯下载链接启⽤了⾓⾊服务的IIS 7或更⾼版本。
URL重写模块已安装。
有关更多信息,请参见使⽤URL重写模块。
设置测试⽹页为了演⽰URL重写模块如何⼯作,我们将使⽤⼀个简单的测试页⾯。
该页⾯读取Web服务器变量,并在浏览器中输出它们的值。
复制以下代码,并将其放在名为article.aspx的⽂件的%SystemDrive%\ inetpub \ wwwroot \⽂件夹中:<%@ Page Language="C#" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>URL Rewrite Module Test</title></head><body><h1>URL Rewrite Module Test Page</h1><table><tr><th>Server Variable</th><th>Value</th></tr><tr><td>Original URL: </td><td><%= Request.ServerVariables["HTTP_X_ORIGINAL_URL"] %></td></tr><tr><td>Final URL: </td><td><%= Request.ServerVariables["SCRIPT_NAME"] + "?" + Request.ServerVariables["QUERY_STRING"] %></td></tr></table></body></html>创建重写规则我们将创建⼀个简单的重写规则,该规则将使⽤以下格式重写URL:⾄:我们将使⽤IIS管理器中的URL重写UI创建⼀个重写规则。
url重写的方法URL重写是一种常见的网络技术,用于将特定的请求映射到特定的资源。
它通常用于隐藏实际文件路径、实现动态内容生成以及实现路由优化等。
本文将详细介绍URL重写的基本概念、步骤以及一些常见的应用场景。
一、基本概念URL重写是一种将特定请求映射到特定资源的机制。
它通过在Web 服务器上配置规则来实现,这些规则通常存储在Web服务器的配置文件中。
当有请求到达Web服务器时,服务器会根据配置的规则对请求进行匹配和处理。
二、步骤1. 确定需要重写的URL模式:首先,你需要确定你想要重写的URL模式。
这些URL模式可以是静态的,也可以是动态的,具体取决于你的需求。
2. 配置规则:根据你的URL模式,在Web服务器的配置文件中添加相应的规则。
这些规则将定义如何将请求映射到特定的资源。
3. 测试和调试:完成配置后,通过浏览器或抓包工具测试你的URL重写规则是否正常工作。
你可以通过更改请求的URL来检查是否按预期映射到正确的资源。
4. 维护和更新:URL重写规则通常需要定期维护和更新,以确保它们仍然按预期工作,并适应你的应用程序的需求变化。
三、应用场景1. 隐藏实际文件路径:通过URL重写,你可以将特定的请求映射到不同的文件路径,从而隐藏实际的文件位置。
这有助于保护敏感信息,并提高网站的安全性。
2. 动态内容生成:URL重写可用于生成动态内容。
通过在规则中嵌入变量或查询参数,你可以根据不同的请求生成不同的内容。
这使得内容更具灵活性和可定制性。
3. 实现路由优化:URL重写可用于实现路由优化,以提高网站的性能和用户体验。
通过将请求映射到最合适的资源路径,你可以减少路由延迟,提高页面加载速度。
4. 跨站请求伪造保护:通过URL重写,你可以将请求映射到特定的安全处理程序,从而实现对跨站请求伪造(CSRF)的保护。
这有助于增强网站的安全性,减少潜在的安全风险。
四、常见工具和框架在进行URL重写时,你需要选择合适的工具和框架来支持你的需求。
goahead的认证和自定义登陆页面的cookie使用【原创】Author:张继飞goahead认证,允许下面几种方式。
NONE - the URL page cannot be accessed.FULL - the URL can always be accessed, without authentication.BASIC - BAA is required before the page can be accessed.DIGEST - DAA is required before the page can be accessed.在开源代码中的定义分别为NONE 0FULL 1BASIC 2DIGEST 3使用认证要通过umconfig.txt文件来分析。
这个文件要与webs可执行程序放在同一目录下。
TABLE=usersROW=0name=adminpassword=X3Ygroup=Administratorprot=0disable=0ROW=1name=guestpassword=M\8group=Administratorprot=0disable=0TABLE=groupsROW=0name=Administratorpriv=4method=1prot=0disable=0TABLE=accessROW=0name=/method=0secure=0group=Administrator通过um中的代码我们可以知道,认证方式是由TABLE=groups 中的method=1控制,然后才是TABLE=access中的method=1,这个method正好对应上面的四种方式(0-3)(可以自己修改一下就看到了不同)。
下面说一下TABLE=access中的 name=/ 列,这就是具体受限区域,也就是说我们要访问“/”也就是根目录时,便会发出请求认证,若name=/home.asp时,我们访问其他数据(页面)时,不会出现认证,但访问home.asp时,服务器便会发送请求认证,浏览器弹出认证页面(当然,我们的method为0或1时不会弹出认证页面)。
通过自定义Module实现URl重写和登陆验证首先我们新建一个类库命名为Module,然后新建一个类命名为UrlRewriteModule 并且实现IHttpHandler接口代码如下public class UrlRewriteModule:IHttpModule{public void Dispose(){throw new NotImplementedException();}public void Init(HttpApplication context){throw new NotImplementedException();}}先别管Dispose方法咱看下Init方法重命名上来看是不是就是初始化的意思啊!然后看它的参数HttpApplication 想想咱有这个东西了是不是就能做点什么事了嘿嘿,废话少说先输出个HelloWorld吧!!!好转到HttpApplication的定义,是不是看到有个BeginRequest的事件 public event EventHandler BeginRequest;从单词上来看这个事件是不是应用程序以开始最先执行的事件吧对没错,好下面咱就实现应用程序一开始执行就向页面中输入一行文字hello worldpublic class UrlRewriteModule:IHttpModule{public void Dispose(){throw newNotImplementedException();}public void Init(HttpApplication context){context.BeginRequest += new EventHandler(context_BeginRequest);}void context_BeginRequest(object sender, EventArgs e){HttpApplication app = sender as HttpApplication;app.Response.Write("hello world");}}那下一步干什么呢?咱只定义了这么个类怎么让应用程序知道它的存在呢?好下面打开web.config文件然后加入如下代码注意在system.web节点中<httpModules><add name="UrlRewriteModule" type="Moduel.UrlRewriteModule"/></httpModules>第一个参数name 就是刚才定义的那个类名。
第二个参数type就是程序集名加类名,好大功告成行大概步骤知道了咱就实现下URL重新的功能吧!需求:把原始的HomeDetail.aspx?Id=1 重写成HomeDetail-1.html 是不是就是伪静态啊!差不多吧呵呵下面看下代码关键性的几行代码void context_BeginRequest(object sender, EventArgs e){HttpApplication app = sender as HttpApplication;//app.Context.Response.Write("hahahahaa~~~");string requestPath = app.Context.Request.FilePath;string fileName = System.IO.Path.GetFileName(requestPath);Regex reg = new Regex("HomeDetail-(\\d+).html");Match m = reg.Match(fileName);if (m.Success){string id = m.Groups[1].Value;app.Context.RewritePath("HomeDetail.aspx?Id=" + id);}//app.Context.Response.Write(fileName);}首先获得当前请求的虚拟路径,然后获得具体的文件名称,通过正则表达式把Id提取出来最后重写路径。
HomeList.aspx 页面做如下处理<!-- 原始是转向地址--><a href = "HomeDetail.aspx?Id=<%# Eval("Id") %>"><%#Eval("Name") %></a><!-- 重写后的地址地址--><a href = "HomeDetail-<%# Eval("Id") %>.html"><%#Eval("Name") %></a>下面运行一下ok 搞定,注意:关于url重写,微软已经为我们开发了一个组件urlrewrite 同过这个组件只需要简单的配置一下配置文件就ok了,感兴趣的可以搜一下。
感觉还没过瘾是吧好下面再整个登陆验证的东东以前我们做是否登陆验证就是在每个需要验证的页面的page_load中都要判断session的值如果为空就转向登陆界面如果不为空继续执行对不,好今天咱就来写个Module来实现这么个功能让其全应用程序有效,通过查找资料发现在HttpApplication类的17个事件中只有两个事件能操作到session1. AcquireRequestState2. PostRequestHandlerExecute 今天呢咱就用第一种首先在Module类库里新建一个类SessionModule写这么几行代码1 class SessionModule:IHttpModule2 {34 public void Init(HttpApplication context)5 {6 context.AcquireRequestState += new EventHandler(context_AcquireRequestState);7 }89 void context_AcquireRequestState(object sender, EventArgs e)10 {11 HttpApplication app = sender as HttpApplication;12 string requestPath = app.Request.Path;13 string fileName = System.IO.Path.GetFileName(requestPath);14 if (app.Context.Session["userInfo"] == null && ! fileName.Equals("login.aspx"))15 {16 app.Response.Redirect("login.aspx");17 }18 }1920212223 public void Dispose()24 {25 throw new NotImplementedException();26 }27 }14 行判断session 是否为空以及请求的页面是否为不是登陆界面如果都成立的话就转向login.aspx 页面中去就这么简单在web.config 文件中加入一下代码<httpModules><add name="UrlRewriteModule" type="Moduel.UrlRewriteModule"/><add name="SessionModule" type="Moduel.SessionModule"/></httpModules>ok 运行一下直接进HomeList.aspx 页面ok 大功告成嘿嘿最后附上HttpAppliction 中的事件执行循序需要的时候可以查一下1. BeginRequest(在 响应请求时作为HTTP 执行管线链中的第一个事件发生)本文用到的2. AuthenticateRequest (当安全模块已建立用户标识时发生。
注:AuthenticateRequest 事件发出信号表示配置的身份验证机制已对当前请求进行了身份验证。
预订AuthenticateRequest 事件可确保在处理附加的模块或事件处理程序之前对请求进行身份验证。
)3. PostAuthenticateRequest (注意:该事件在.NET Framework 2.0 版中是新增的。
当安全模块已建立用户标识时发生。
PostAuthenticateRequest 事件在AuthenticateRequest 事件发生之后引发。
预订PostAuthenticateRequest 事件的功能可以访问由PostAuthenticateRequest 处理的任何数据。
)4. AuthorizeRequest (当安全模块已验证用户授权时发生。
AuthorizeRequest 事件发出信号表示 已对当前请求进行了授权。
预订AuthorizeRequest 事件可确保在处理附加的模块或事件处理程序之前对请求进行身份验证和授权。
)5. PostAuthorizeRequest (.NET 2.0里新增的事件。
在当前请求的用户已获授权时发生。
PostAuthorizeRequest 事件发出信号表示 已对当前请求进行了授权。
预订PostAuthorizeRequest 事件可确保在处理附加的模块或处理程序之前对请求进行身份验证和授权。
)6. ResolveRequestCache (当 完成授权事件以使缓存模块从缓存中为请求提供服务时发生,从而跳过事件处理程序(例如某个页或XML Web services)的执行。
)7. PostResolveRequestCache (在 跳过当前事件处理程序的执行并允许缓存模块满足来自缓存的请求时发生。
)在PostResolveRequestCache 事件之后、PostMapRequestHandler 事件之前创建一个事件处理程序(对应于请求URL 的页)。
8. PostMapRequestHandler(在 已将当前请求映射到相应的事件处理程序时发生。