Um tutorial que o novato pode entender - Django implementa logon único (SSO)

Um tutorial que o novato pode entender - Django implementa logon único (SSO)

  Olá a todos, meu nome é qí guān jié (qí guān jié), eu registro o processo de aprendizagem em CSDN, o tempo voa, o futuro é promissor, vamos lá ~ O blogueiro atualmente apenas bloga em CSDN, o único endereço de atualização de blog é: Qí Guan Jie ‘s blog ao mesmo tempo, estou tentando compartilhar algum conteúdo na estação B. a homepage da estação B é: a página inicial da estação B de Qiguanjie

Este artigo foi escrito originalmente por Qiguanjie. Apoie o artigo original. Algumas plataformas têm roubado artigos de blogueiros de forma maliciosa! ! !
Se precisar entrar em contato com o blogger, você pode entrar em contato comigo no WeChat: qiguanjie2015


Introdução ao SSO

A função Single Sign On (Single Sign On) é uma função muito comum, especialmente quando precisamos fazer login e sincronizar entre vários sistemas. Por exemplo, depois de fazer login no espaço QQ, vamos para outros sites QQ e fazemos login por padrão. Status, este é o logon único.

Há muitas maneiras de conseguir o logon único; aqui está uma maneira de conseguir por meio de sessão compartilhada. O que você precisa fazer para realizar a sessão compartilhada é permitir que vários aplicativos diferentes compartilhem a mesma sessão, mas a sessão padrão é que cada aplicativo tenha uma sessão e um cookie separados, portanto, o armazenamento da sessão precisa ser configurado aqui.

Além do armazenamento de sessão padrão, também posso definir a sessão para ser armazenada em um arquivo, cache ou banco de dados.

Se permitirmos que a sessão seja armazenada em um local ou banco de dados fixo, definiremos o domínio de cada cookie do aplicativo como o endereço do domínio pai para obter o mesmo para cada cookie, de modo que o ID da sessão armazenado em cada cookie seja o mesmo.

Configure um ambiente de teste

Vamos criar dois projetos Django vazios para demonstração, SSO1 e SSO2. Aqui, pycharm é usado para criar dois projetos Django diretamente, ou pode ser criado na linha de comando django-admin startproject sso, onde ssoé o nome do projeto criado. Também é possível usar dois projetos idênticos aqui e iniciá-los em endereços diferentes, mas para o propósito de demonstrar o efeito, dois são criados aqui.

Insira a descrição da imagem aqui

Depois de criar os dois projetos, precisamos escrever uma função simulada de login e logout para o projeto.
Em templatesCriar um arquivo de pasta de login.htmlarquivos. O código da página de login escrito antes é usado diretamente aqui, o estilo não é adicionado e é adicionado em SSO1 e SSO2 login.html. O código específico é:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="login_content">
    <div class="page-header" id="page_header">
      <h1>登录<small>Login</small></h1>
    </div>
    <div id="login_form">
        <form method="post">
          <div class="form-group">
            <label for="exampleInputEmail1">Email address</label>
            <input type="input" class="form-control" name="usr" id="exampleInputEmail1" placeholder="username">
          </div>
          <div class="form-group">
            <label for="exampleInputPassword1">密码</label>
            <input type="password" class="form-control" name="password" id="exampleInputPassword1" placeholder="密码">
          </div>
          <div id="login_butt">
              <button type="submit" class="btn btn-default">登录</button>
              <button type="button" class="btn btn-default" onclick="">注册</button>
          </div>
        </form>
    </div>
</div>
</body>
</html>

Em seguida, SSO1crie um view.pyarquivo na pasta para armazenar a função de visualização. (Aqui é apenas para demonstrar o SSO, nenhum módulo é dividido.)
O diretório do arquivo após a criação do arquivo é: (o projeto SSO2 é o mesmo)

.
├── SSO1
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   ├── view.py
│   └── wsgi.py
├── manage.py
├── templates
│   └── login.html
└── venv
    ├── bin
    ├── include
    ├── lib
    └── pyvenv.cfg

Insira um pequeno bug

No ambiente operacional macbook, o aplicativo Django criado por pycharm às vezes tem um bug em sua inicialização. Se a biblioteca do sistema operacional estiver ausente, um erro será relatado:

Traceback (most recent call last):
  File "/Users/qiguan/Documents/develop_files/python_files/SSO1/manage.py", line 22, in <module>
    main()
  File "/Users/qiguan/Documents/develop_files/python_files/SSO1/manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/Users/qiguan/Documents/develop_files/python_files/SSO1/venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
    utility.execute()
  File "/Users/qiguan/Documents/develop_files/python_files/SSO1/venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 345, in execute
    settings.INSTALLED_APPS
  File "/Users/qiguan/Documents/develop_files/python_files/SSO1/venv/lib/python3.7/site-packages/django/conf/__init__.py", line 82, in __getattr__
    self._setup(name)
  File "/Users/qiguan/Documents/develop_files/python_files/SSO1/venv/lib/python3.7/site-packages/django/conf/__init__.py", line 69, in _setup
    self._wrapped = Settings(settings_module)
  File "/Users/qiguan/Documents/develop_files/python_files/SSO1/venv/lib/python3.7/site-packages/django/conf/__init__.py", line 170, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/Users/qiguan/Documents/develop_files/python_files/SSO1/SSO1/settings.py", line 57, in <module>
    'DIRS': [os.path.join(BASE_DIR, 'templates')]
NameError: name 'os' is not defined

Se houver um erro, basta setting.pyimportar os em:import os


Em seguida, escrevemos as funções de login e logout no view.py dos dois projetos:

from django.http import HttpResponse
from django.shortcuts import render, redirect


def login(request):
    if request.method == 'GET':
        if 'usr' in request.session:
            # 如果session中已有信息,则显示
            usr = request.session['usr']
            password = request.session['password']
            return HttpResponse("usr:{},password:{},sessionid:{},cookie:{}".format(usr,password,request.session.session_key,request.COOKIES))
        return render(request,'login.html')
    if request.method == 'POST':
        usr = request.POST['usr']
        password = request.POST['password']
        request.session['usr'] = usr
        request.session['password'] = password
        return HttpResponse(
            "usr:{},password:{},sessionid:{},cookie:{}".format(usr, password, request.session.session_key,
                                                               request.COOKIES))


def logout(request):
    request.session.clear()
    return redirect('/login')

Em url.pyadicionar informações de roteamento:

"""SSO1 URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.1/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from . import view
urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/',view.login),
    path('logout/',view.logout),
]

Django é configurado com csrf por padrão, você precisa comentá-lo, settings.pypesquisar por csrf no arquivo e comentar.
O settings.pyarquivo revisado é:

"""
Django settings for SSO1 project.

Generated by 'django-admin startproject' using Django 3.1.7.

For more information on this file, see
https://docs.djangoproject.com/en/3.1/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.1/ref/settings/
"""

from pathlib import Path
import os

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'o=blc^vzeb1&g*b!si(wtxe44_=i5cv(3jqm2*u2u&7vgj%&=%'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'SSO1.urls'

TEMPLATES = [
    {
    
    
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')]
        ,
        'APP_DIRS': True,
        'OPTIONS': {
    
    
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'SSO1.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases

DATABASES = {
    
    
    'default': {
    
    
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}


# Password validation
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
    
    
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
    
    
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
    
    
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
    
    
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/

STATIC_URL = '/static/'

Em seguida, faça a migração do banco de dados para os dois projetos e crie algumas bibliotecas básicas para projetos Django:
python3 manage.py migrate
Ambos os projetos têm a mesma configuração, de modo que nossos dois projetos atualmente testados são configurados e, em seguida, os iniciamos em portas diferentes. Aqui, nós o iniciamos diretamente manualmente, começando nas portas 5000 e 6000, respectivamente.
python3 manage.py runserver 127.0.0.1:5000
python3 manage.py runserver 127.0.0.1:7000
Comece dois projetos:
Insira a descrição da imagem aqui
Insira a descrição da imagem aqui

Agora abrimos http://127.0.0.1:5000/login/e respectivamente no navegador, e as http://127.0.0.1:7000/login/páginas exibidas são todas páginas de login, que são exibidas da seguinte forma:

Insira a descrição da imagem aqui

Neste momento, http://127.0.0.1:5000/login/inserimos a senha da conta aleatoriamente e clicamos para fazer o login, exibindo:

usr:123,password:123,sessionid:None,cookie:{'csrftoken': '8YPzJbY03sHJUZH6kdFZzr9TkDtdVTKflgDDeIn0wgGC6cAeudcrkXLyIxXBEnzG'}

Neste momento, entramos http://127.0.0.1:7000/login/e descobrimos que neste aplicativo, a página anterior foi exibida, e o login não foi sincronizado. Vamos implementar nosso SSO. O método de implementação aqui é muito simples. Aqui estão dois métodos de implementação: 1. Armazene a sessão no mesmo arquivo, 2. Armazene a sessão no Redis

Armazene a sessão no mesmo arquivo para obter SSO

Criamos uma pasta de sessão sob o arquivo SSO2. A localização desta pasta é arbitrária, basta escrever o caminho absoluto.

Em seguida, settings.pyconfiguramos o cookie e a sessão nos dois projetos ,

# 设置cookie的domain为父域domain,
# 如果是使用域名,以百度为例,主域名为`www.baidu.com`,旗下各个应用为:'asd.baidu.com'
# 则这里设置为:`.baidu.com`
SESSION_COOKIE_DOMAIN = '127.0.0.1'

# 设置session存储在文件中
SESSION_ENGINE = 'django.contrib.sessions.backends.file'
# 设置存储位置,这里设为绝对路径
SESSION_FILE_PATH = '/Users/qiguan/Documents/develop_files/python_files/SSO2/session'

Observe que a configuração aqui é a mesma, mas se os dois nomes de projeto forem diferentes, você não pode settings.pycopiar diretamente um completo para o outro, porque existem algumas configurações de projeto, por exemplo ROOT_URLCONF = 'SSO1.urls', WSGI_APPLICATION = 'SSO1.wsgi.application'as anteriores são todos os nomes de projetos precisam ser distinguidos .

Neste momento que estamos abrindo http://127.0.0.1:5000/login/, digite a senha da conta, esta página exibe:

usr:123,password:123,sessionid:2bs2nx2iq879epxu7au7o1zq63o095v7,cookie:{'sessionid': '2bs2nx2iq879epxu7au7o1zq63o095v7', 'csrftoken': '8YPzJbY03sHJUZH6kdFZzr9TkDtdVTKflgDDeIn0wgGC6cAeudcrkXLyIxXBEnzG'}

Neste momento, estamos abrindo http://127.0.0.1:7000/login/, acessamos diretamente sem fazer login, e descobrimos que o mesmo conteúdo é exibido, ou seja, estamos usando o mesmo conteúdo, e o SSO está implementado.

Use o Redis para implementar o SSO

Usar o sistema de arquivos para implementar uma sessão compartilhada não causará problemas em um pequeno sistema simultâneo, mas se a quantidade de simultaneidade for grande, alguns problemas ocorrerão, portanto, apresentaremos a implementação usando o Redis aqui.

Você precisa instalar o Redis por conta própria e instalar o Django-redis no Python usado pelos dois projetos:
pip3 install django-redis

Depois de fazer isso, modifique o arquivo settings.py, comente a configuração da sessão de armazenamento de arquivos e modifique-o para:


# # 设置session存储在文件中
# SESSION_ENGINE = 'django.contrib.sessions.backends.file'
# # 设置存储位置,这里设为绝对路径
# SESSION_FILE_PATH = '/Users/qiguan/Documents/develop_files/python_files/SSO2/session'

# 使用Redis存储session
CACHES = {
    
    
    "default": {
    
    
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379",
        "OPTIONS": {
    
    
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {
    
    "max_connections": 100}
            # "PASSWORD": "123",
        }
    }
}

SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'default'
SESSION_COOKIE_AGE = 60 * 5

Neste ponto, vamos testar os dois aplicativos novamente. Neste momento, primeiro visitamos o logout, limpamos a sessão e, em seguida, visitamos :, http://127.0.0.1:5000/login/Depois de inserir a senha da conta, será exibido:

usr:123,password:123,sessionid:None,cookie:{'csrftoken': '8YPzJbY03sHJUZH6kdFZzr9TkDtdVTKflgDDeIn0wgGC6cAeudcrkXLyIxXBEnzG'}

Neste momento, nós visitamos http://127.0.0.1:7000/login/(não logamos) e exibimos as mesmas informações de usuário e senha.

Neste momento, nosso SSO também pode ser implementado normalmente.

Bem, este artigo vai parar por aqui primeiro, se você precisar, você pode implementá-lo de acordo com o seu negócio específico, então não vou entrar em detalhes aqui. Escreverei alguns blogs de desenvolvimento relacionados ao Django quando tiver tempo no futuro.


  Olá a todos, meu nome é qí guān jié (qí guān jié), eu registro o processo de aprendizagem em CSDN, o tempo voa, o futuro é promissor, vamos lá ~ O blogueiro atualmente apenas bloga em CSDN, o único endereço de atualização de blog é: Qí Guan Jie ‘s blog ao mesmo tempo, estou tentando compartilhar algum conteúdo na estação B. a homepage da estação B é: a página inicial da estação B de Qiguanjie

Este artigo foi escrito originalmente por Qiguanjie. Apoie o artigo original. Algumas plataformas têm roubado artigos de blogueiros de forma maliciosa! ! !
Se precisar entrar em contato com o blogger, você pode entrar em contato comigo no WeChat: qiguanjie2015


Acho que você gosta

Origin blog.csdn.net/qq_43422111/article/details/114435883
Recomendado
Clasificación