日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Django进阶-auth集成认证模块

發布時間:2023/11/27 生活经验 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Django进阶-auth集成认证模块 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  auth認證模塊是Django內置集成的一個用戶認證模塊。
  
  auth認證模塊方法
  
  方法 釋義
  
  auth.authenticate() 認證校驗
  
  auth.login(request,user) 封裝認證了的user對象
  
  auth.logout(request) 將session數據都刪除,且cookie也失效
  
  auth認證模塊示例
  
  from django.shortcuts import render,redirect
  
  from django.contrib import auth
  
  from django.contrib.auth.decorators import login_required
  
  def login(request):
  
  if request.method == "POST":
  
  user = request.POST.get("username")
  
  pwd = request.POST.get("password")
  
  user = auth.authenticate(username=user, password=pwd)
  
  # auth認證校驗,如果校驗成功返回用戶名,否則返回空
  
  if user:
  
  auth.login(request, user)
  
  # 封裝認證了的user對象
  
  return redirect("index.html")
  
  return render(request, "login.html")
  
  auth認證模塊裝飾器使用
  
  裝飾器,未登錄認證時無法訪問 index 默認跳轉到指定頁面,在setting中 配置LOGIN_URL = "跳轉的頁面名稱" 如:
  
  LOGIN_URL = "login.html"
  
  @login_required
  
  def index(request):
  
  print("登錄的用戶是:",request.user.username)
  
  return render(request,"index.html")
  
  auth認證模塊實例
  
  目錄架構
  
  MyDjango
  
  APP
  
  html
  
  css
  
  images
  
  js
  
  static
  
  index.html
  
  login.html
  
  migrations
  
  views
  
  index.py
  
  MyDjango
  
  settings.py
  
  urls.py
  
  wsgi.py
  
  db.sqlite3
  
  manage.py
  
  配置文件
  
  index.html
  
  <!DOCTYPE html>
  
  <html lang="en">
  
  <head>
  
  <meta charset="UTF-8">
  
  <title>wellcome</title>
  
  </head>
  
  <body>
  
  {% csrf_token %}
  
  <h1>wellcome index web !!!</h1>
  
  <a href="login.html">退出</a>
  
  </body>
  
  </html>
  
  login.html
  
  <!DOCTYPE html>
  
  <html lang="en">
  
  <head>
  
  <meta charset="UTF-8">
  
  <title>Title</title>
  
  </head>
  
  <body>
  
  <form method="post" action="login.html">
  
  {% csrf_token %}
  
  用戶名:<input type="text" name = "username">
  
  密碼: <input type="text" name = "password">
  
  <input type="submit">
  
  </form>
  
  </body>
  
  </html>
  
  index.py
  
  from django.shortcuts import render,redirect,HttpResponse
  
  from django.contrib import auth
  
  from django.contrib.auth.decorators import login_required
  
  def login(request):
  
  auth.logout(request)
  
  if request.method == "POST":
  
  user = request.POST.get("username")
  
  pwd = request.POST.get("password")
  
  print("用戶名:",user,"密碼:",pwd)
  
  user = auth.authenticate(username=user, password=pwd)
  
  # auth認證校驗,如果校驗成功返回用戶名,否則返回空
  
  if user:
  
  auth.login(request, user)
  
  # 封裝認證了的user對象
  
  return redirect("/index.html")
  
  else:
  
  return HttpResponse("登錄失敗,用戶或密碼錯誤!")
  
  return render(request, "login.html")
  
  @login_required
  
  def index(request):
  
  user = request.user.username
  
  print("用戶",user,"登錄成功!")
  
  return render(request, "index.html",{"user":user})
  
  settings.py
  
  TEMPLATES
  
  'DIRS': [os.path.join(BASE_DIR, 'APP/html/static')]
  
  STATIC_URL = '/static/'
  
  STATICFILES_DIRS = (os.path.join(BASE_DIR,"APP/html/static"),)
  
  STATIC_ROOT = 'APP/html'
  
  LOGIN_URL = "login.html"
  
  urls.py
  
  from django.contrib import admin
  
  from django.urls import path,re_path
  
  from APP.views import index
  
  urlpatterns = [
  
  path('admin/', admin.site.urls),
  
  re_path('^login.html$', index.login),
  
  re_path('^index.html$', index.index),
  
  ]
  
  服務運行
  
  生成數據表
  
  python manage.py makemigrations APP
  
  python manage.py migrate
  
  創建超級用戶用于登錄測試
  
  python manage.py createsuperuser
  
  服務運行
  
  python manage.py runserver
  
  復制代碼
  
  可以看到只增加了一個類,這個類有個特點 1. 它實現了 InvocationHandler 接口 2. 它的 invoke 方法實現了我們的需求。InvocationHandler 是 Java 動態代理定義的一個接口,接口中定義了一個 invoke 方法,我們調用代理對象的任何方法都會變成對 FileWriterInvocationHandler 對象的 invoke 方法的調用, 在 invoke 方法中完成代理的功能并控制對真實對象的調用。如果看到你覺得一頭霧水,沒關系繼續向下看將豁然開朗。
  
  到目前為止我們只看到新增了一個 InvocationHandler 接口的實現類,并沒有看到代理對象。之前說過之所以是動態代理是因為在運行時才創建代理類,因此我們需要編寫一個驅動程序,動態創建代理對象,完成動態代理的后半部分。
  
  復制代碼
  
  package com.cnblogs.duma.dp.proxy.dynamic;
  
  import java.lang.reflect.Proxy;
  
  public class DynamicProxyDriver {
  
  public static void main(String[] args) {
  
  /**
  
  * Proxy.newProxyInstance 包括三個參數
  
  * 第一個參數:定義代理類的 classloader,一般用被代理接口的 classloader
  
  * 第二個參數:需要被代理的接口列表
  
  * 第三個參數:實現了 InvocationHandler 接口的對象
  
  * 返回值:代理對象
  
  */
  
  Writer writer = (Writer) Proxy.newProxyInstance(
  
  Writer.class.getClassLoader(),
  
  new Class[www.baohuayule.com]{Writer.class},
  
  new FileWriterInvocationHandler(new FileWriter())); //這就是動態的原因,運行時才創建代理類
  
  try {
  
  writer.write("file1.txt", "text"); //調用代理對象的write方法
  
  } catch (Exception e) {
  
  e.printStackTrace();
  
  }
  
  writer.write("file2.txt", new byte[]{}); //調用代理對象的write方法
  
  }
  
  }
  
  復制代碼
  
  最關的一步是 Proxy.newProxyInstance ,該調用會創建代理對象,該代理對象會將我們需要代理的接口(Writer)和 InvocationHandler 實現類關聯起來。這樣代理對象就會有 Writer 接口的 2 個方法,針對我們的業務邏輯調用過程為:調用代理對象 writer 的 write 方法寫數據 -> 轉到 FileWriterInvocationHandler 對象的 invoke 方法,判斷磁盤空間是否夠用 -> 拋出磁盤空間不足異常或調用 FileWriter 對象的 write 方法寫數據。在這里動態代理涉及到了 Writer 接口及其實現類、InvocationHandler 接口及其實現類、代理類。動態代理 UML 類圖如下:
  
  可以看到代理類 Proxy 實現了 Writer 接口,因此可以調用 write 方法,同時代理類關聯 FileWriterInvocationHandler ,因此對 write 方法的調用會變成對 invoke 方法的調用。
  
  至此,新的需求就完成了,我們結合代理模式談談此次需求變更我們用到了哪些好的設計原則。
  
  1. 我們沒有在原有 FileWrite 實現類中修改代碼, 而是新增了 FileInvocationHandler 實現新需求,這符合設計原則中的開閉原則,即:對擴展開發對修改封閉。改動現有代碼容易影響已有的正常代碼
  
  2. 我們增加代理之后只是把 Writer writer = new FileWriter() 改為 Writer writer = Proxy.newProxyInstance(...),由于都繼承了 Writer 接口,因此不需要修改 writer 的類型, 這符合面向接口的設計原則,讓我們盡量少的改動現有代碼
  
  動態代理還有一個重要的應用場景,我們可以在 invoke 方法中把待調用的方法名(method)和參數(args)發送到遠程服務器,在遠程服務器中完成調用并返回一個結果,這其實就是 RPC (remote procedure call),即:遠程過程調用。我在閱讀 Hadoop 源碼過程中發現 Hadoop RPC 將動態代理技術應用在上述場景中。
  
  遠程代理
  
  個人覺得上述動態代理第二個應用場景算是遠程代理的一個特例,因為遠程代理不一定非要動態創建代理對象。接下來我們以 Java RMI 為例, 簡單看下遠程代理。RMI(remote method invocation)即:遠程方法調用,與 RPC 類似,可以讓我們像調用 Java 本地方法一樣,調用遠程的方法。這里就需要一個代理對象,代理對象實現了本地的接口,其中序列化/反序列化以及網絡傳輸都在代理對象中實現, 對我們透明,這也是控制了我們對遠程對象的訪問。代碼如下:
  
  復制代碼
  
  import java.rmi.Remote;
  
  import java.rmi.RemoteException;
  
  /**
  
  * 定義一個接口,接口中的方法要在遠程調用
  
  */
  
  public interface MyRemote extends Remote {
  
  public String sayHello(www.gouyiflb.cn/ ) throws RemoteException;
  
  }
  
  復制代碼
  
  復制代碼
  
  import java.net.MalformedURLException;
  
  import java.rmi.Naming;
  
  import java.rmi.RemoteException;
  
  import java.rmi.server.UnicastRemoteObject;
  
  /**
  
  * 定義一個接口的遠程實現類
  
  * 為了讓遠程對象擁有 “遠程的” 功能,需要繼承 UnicastRemoteObject 類
  
  */
  
  public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote {
  
  protected MyRemoteImpl() throws RemoteException {
  
  }
  
  /**
  
  * 客戶端通過 rmi 代理對象調用 sayHello 方法,將會進入到此方法
  
  * @return
  
  * @throws RemoteException
  
  */
  
  @Override
  
  public String sayHello(www.365soke.com) throws RemoteException {
  
  System.out.println("req from client.");
  
  return "Server says, 'Hey'";
  
  }
  
  /**
  
  * 啟動遠程進程的 main 方法
  
  * @param args
  
  */
  
  public static void main(String[www.lezongyule.com] args) {
  
  try {
  
  MyRemote service = new MyRemoteImpl(www.shengyunyule.cn);
  
  Naming.rebind("RemoteHello", service); //將服務名和對應的服務進行綁定,客戶端會根據 RemoteHello 找到遠程服務
  
  } catch (RemoteException e) {
  
  e.printStackTrace();
  
  } catch (MalformedURLException e) {
  
  e.printStackTrace();
  
  }
  
  }
  
  }
  
  復制代碼
  
  這樣我們的遠程服務已經寫好了,還需要做以下 3 個工作來啟動遠程服務
  
  1. 生成客戶端代理類,需要在 MyRemoteImpl.class 所在的目錄中執行 rmic MyRemoteImpl 命令,將會生成 MyRemoteImpl_Stub.class 類。首先,rmic 命令是 jdk 自帶命令,所在的目錄與 java 和 javac 所在的目錄一樣;其次,我用的 Idea 創建的普通 Java 工程,我的 MyRemoteImpl.class 文件在“E:\backends\java-backends\java-ex\out\production\java-ex”目錄中,以我的工程為例,路徑以及命令執行如下:
  
  E:\backends\java-backends\java-ex\out \www.yun-shengyl.com production\java-ex>rmic MyRemoteImpl
  
  2. 啟動 rmiregistry,為了遠程服務可以注冊服務名,在我們的 class 所在的目錄(“項目目錄\out\production\java-ex”)中執行 rmiregistry 命令
  
  E:\backends\java-backends\java-ex\out\production\java-ex>rmiregistry
  
  3. 運行 MyRemoteImpl 類,啟動遠程服務進程
  
  繼續編寫客戶端訪問代碼,客戶端代碼主要是找到剛剛注冊的 RemoteHello 遠程服務,并獲得代理對象,調用代理對象上的方法。我們可以在同一個工程下,創建 MyRemoteClient 類
  
  復制代碼
  
  import java.net.MalformedURLException;
  
  import java.rmi.Naming;
  
  import java.rmi.NotBoundException;
  
  import java.rmi.RemoteException;
  
  public class MyRemoteClient {
  
  public static void main(String[www.suoLaiervip.com] args) {
  
  try {
  
  /**
  
  * 找到遠程服務,并返回代理對象
  
  * 該代理對象就是 MyRemoteImpl_Stub 且實現了 MyRemote 接口
  
  */
  
  MyRemote service = (MyRemote) Naming.lookup("rmi://127.0.0.1/RemoteHello");
  
  /**
  
  * 調用代理對象的 sayHello 方法,便會通過代理將調用發送到遠程服務進程并返回結果
  
  */
  
  String ret = service.sayHello();
  
  System.out.println(ret);
  
  } catch (RemoteException e) {
  
  e.printStackTrace(www.qwert888.com/);
  
  } catch (NotBoundException e) {
  
  e.printStackTrace();
  
  } catch (MalformedURLException e) {
  
  e.printStackTrace();
  
  }
  
  }
  
  }
  
  復制代碼
  
  我們可以直接運行 MyRemoteClient 類,可以看到在剛啟動的 MyRemoteImpl 進程中,控制臺打印了
  
  req from client.
  
  在 MyRemoteClient 進程的控制臺中打印了
  
  Server says, 'Hey'
  
  至此我們的遠程代理已經介紹完畢。
  
  虛擬代理
  
  虛擬代理是作為創建開銷大的對象的替身。舉一個我們常見的例子,在 Web 開發或者移動端開發的時候經常會用到 Image 組件,Image 組件一般要傳入一個 URL 參數,從網絡上下載圖片到本地展示。假設這個組件要等到圖片下載完成才有顯示,那如果圖片較大或者網絡較慢,給用戶造成不好的體驗。解決方法是我們可以先顯示一個 loading 狀態的默認的本地圖片,當遠程圖片下載完成后重新渲染,替換掉當前的 laoding 狀態的圖片。用虛擬代理來實現這個技術就可以定義一個 ImageProxy 類型,在該類中初始時候先展示一個默認圖片,啟動線程創建 Image 對象,Image 對象創建完畢,再重新渲染,替換默認圖片。虛擬代理也是控制了對 Image 對象的訪問。
  
  總結
  
  本章主要介紹了代理模式,并且我們看到了代理模式常用的幾種變形,同時也接觸了面向對象的基本的設計原則
  
  動態代理 - 程序運行時動態地創建代理對象,所有的對代理對象方法的調用都會變成對 InvocationHandler 的 invoke 方法的調用
  
  遠程代理 - 本地調用代理對象訪問遠程的方法,無需關心網絡通信細節,跟調用本地方法一樣
  
  虛擬代理 - 為了創建開銷大的對象而存在
  
  可以看到代理模式最核心就是控制,代理對象的目的就是控制對真實對象的訪問。

轉載于:https://www.cnblogs.com/qwangxiao/p/10638430.html

總結

以上是生活随笔為你收集整理的Django进阶-auth集成认证模块的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。