cari
Rumahpembangunan bahagian belakangTutorial Python详解实现JSON Web Tokens的原理

详解实现JSON Web Tokens的原理

May 02, 2017 pm 03:18 PM
jsonTokensweb

本文主要介绍了JSON Web Tokens的实现原理。具有很好的参考价值,下面跟着小编一起来看下吧

前言

最近在做一个Python项目的改造,将python项目重构为Java项目,过程中遇到了这个知识点,觉得这个蛮实用的,所以下班后回来趁热打铁写下这篇总结,希望后面的人能够有所借鉴,少走弯路。

一、优势简介

JSON Web Tokens简称jwt,是rest接口的一种安全策略。本身有很多的优势:

解决跨域问题:这种基于Token的访问策略可以克服cookies的跨域问题。

服务端无状态可以横向扩展,Token可完成认证,无需存储Session。

系统解耦,Token携带所有的用户信息,无需绑定一个特定的认证方案,只需要知道加密的方法和密钥就可以进行加密解密,有利于解耦。

防止跨站点脚本攻击,没有cookie技术,无需考虑跨站请求的安全问题。

二、原理简介

JSON Web Tokens的格式组成,jwt是一段被base64编码过的字符序列,用点号分隔,一共由三部分组成,头部header,消息体playload和签名sign。

1.jwt的头部Header是json格式:

{
  "typ":"JWT",
  "alg":"HS256",
  "exp":1491066992916
}

其中typ是type的简写,代表该类型是JWT类型,加密方式声明是HS256,exp代表当前时间.

2.jwt的消息体Playload

{
  "userid":"123456",
  "iss":"companyName"
}

消息体的具体字段可根据业务需要自行定义和添加,只需在解密的时候注意拿字段的key值获取value。

3.签名sign的生成

最后是签名,签名的生成是把header和playload分别使用base64url编码,接着用'.‘把两个编码后的字符串连接起来,再把这拼接起来的字符串配合密钥进行HMAC SHA-256算法加密,最后再次base64编码下,这就拿到了签名sign. 最后把header和playload和sign用'.‘ 连接起来就生成了整个JWT。

三、校验简介

整个jwt的结构是由header.playload.sign连接组成,只有sign是用密钥加密的,而所有的信息都在header和playload中可以直接获取,sign的作用只是校验header和playload的信息是否被篡改过,所以jwt不能保护数据,但以上的特性可以很好的应用在权限认证上。

1.加密

比如要加密验证的是userid字段,首先按前面的格式组装json消息头header和消息体playload,按header.playload组成字符串,再根据密钥和HS256加密header.playload得到sign签名,最后得到jwtToken为header.playload.sign,在http请求中的url带上参数想后端服务请求认证。

2. 解密

后端服务校验jwtToken是否有权访问接口服务,进行解密认证,如校验访问者的userid,首先

用将字符串按.号切分三段字符串,分别得到header和playload和sign。然后将header.playload拼装用密钥和HAMC SHA-256算法进行加密然后得到新的字符串和sign进行比对,如果一样就代表数据没有被篡改,然后从头部取出exp对存活期进行判断,如果超过了存活期就返回空字符串,如果在存活期内返回userid的值。

四、代码示例

1.python代码的加密解密

#!/usr/bin/env python
# coding: utf-8

from itsdangerous import BadTimeSignature, SignatureExpired
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer

APP_SECRET_KEY="secret"
MAX_TOKEN_AGE=1800
token_generator = Serializer(APP_SECRET_KEY, expires_in=MAX_TOKEN_AGE)

def generate_auth_token(userid):
  access_token = token_generator.dumps({"userid":userid})
  return access_token
def verify_token(token):
  try:
    user_auth = token_generator.loads(token)
    print type(token_generator)
  except SignatureExpired as e:
    raise e
  except BadTimeSignature as e:
    raise e
  return user_auth

2. java代码的加密解密

package api.test.util;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;

/**
 * jwt加解密实现
 * 
 * @author zhengsc
 */
@Slf4j
public class TokenUtil {

  private String ISSUER = "companyName"; // 机构

  private String APP_SECRET_KEY = "secret"; // 密钥

  private long MAX_TOKEN_AGE = 1800; // 存活期

  /**
   * 生成userId的accessToken
   * 
   * @param userid
   * @return
   */
  public String generateAccessToken(String userid) {
    JSONObject claims = new JSONObject();
    claims.put("iss", ISSUER);
    claims.put("userid", userid);
    String accessToken = sign(claims, APP_SECRET_KEY);
    return accessToken;
  }

  /**
   * 解密程序返回userid
   * 
   * @param token
   * @return
   */
  public String verifyToken(String token) {
    String userid = "";
    try {
      String[] splitStr = token.split("\\.");
      String headerAndClaimsStr = splitStr[0] + "." +splitStr[1];
      String veryStr = signHmac256(headerAndClaimsStr, APP_SECRET_KEY);
      // 校验数据是否被篡改
      if (veryStr.equals(splitStr[2])) {
        String header = new String(Base64.decodeBase64(splitStr[0]),"UTF-8");
        JSONObject head = JSONObject.fromObject(header);
        long expire = head.getLong("exp") * 1000L;
        long currentTime = System.currentTimeMillis();
        if (currentTime <= expire){ // 验证accessToken的有效期
          String claims = new String(Base64.decodeBase64(splitStr[1]),"UTF-8");
          JSONObject claim = JSONObject.fromObject(claims);
          userid = (String) claim.get("userid");
        }
      }
    } catch (UnsupportedEncodingException e) {
      log.error(e.getMessage(), e);
    }

    return userid;
  }

  /**
   * 组装加密结果jwt返回
   * 
   * @param claims
   * @param appSecretKey
   * @return
   */
  private String sign(JSONObject claims, String appSecretKey) {
    String headerAndClaimsStr = getHeaderAndClaimsStr(claims);
    String signed256 = signHmac256(headerAndClaimsStr, appSecretKey);
    return headerAndClaimsStr + "." + signed256;
  }

  /**
   * 拼接请求头和声明
   * 
   * @param claims
   * @return
   */
  private String getHeaderAndClaimsStr(JSONObject claims) {
    JSONObject header = new JSONObject();
    header.put("alg", "HS256");
    header.put("typ", "JWT");
    header.put("exp", System.currentTimeMillis() + MAX_TOKEN_AGE * 1000L);
    String headerStr = header.toString();
    String claimsStr = claims.toString();
    String headerAndClaimsStr = Base64.encodeBase64URLSafeString(headerStr.getBytes()) + "."
        + Base64.encodeBase64URLSafeString(claimsStr.getBytes());
    return headerAndClaimsStr;
  }

  /**
   * 将headerAndClaimsStr用SHA1加密获取sign
   * 
   * @param headerAndClaimsStr
   * @param appSecretKey
   * @return
   */
  private String signHmac256(String headerAndClaimsStr, String appSecretKey) {
    SecretKey key = new SecretKeySpec(appSecretKey.getBytes(), "HmacSHA256");
    String result = null;
    try {
      Mac mac;
      mac = Mac.getInstance(key.getAlgorithm());
      mac.init(key);
      result = Base64.encodeBase64URLSafeString(mac.doFinal(headerAndClaimsStr.getBytes()));
    } catch (NoSuchAlgorithmException | InvalidKeyException e) {
      log.error(e.getMessage(), e);
    }
    return result;
  }

}

Atas ialah kandungan terperinci 详解实现JSON Web Tokens的原理. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Python: Permainan, GUI, dan banyak lagiPython: Permainan, GUI, dan banyak lagiApr 13, 2025 am 12:14 AM

Python cemerlang dalam permainan dan pembangunan GUI. 1) Pembangunan permainan menggunakan pygame, menyediakan lukisan, audio dan fungsi lain, yang sesuai untuk membuat permainan 2D. 2) Pembangunan GUI boleh memilih tkinter atau pyqt. TKInter adalah mudah dan mudah digunakan, PYQT mempunyai fungsi yang kaya dan sesuai untuk pembangunan profesional.

Python vs C: Aplikasi dan kes penggunaan dibandingkanPython vs C: Aplikasi dan kes penggunaan dibandingkanApr 12, 2025 am 12:01 AM

Python sesuai untuk sains data, pembangunan web dan tugas automasi, manakala C sesuai untuk pengaturcaraan sistem, pembangunan permainan dan sistem tertanam. Python terkenal dengan kesederhanaan dan ekosistem yang kuat, manakala C dikenali dengan keupayaan kawalan dan keupayaan kawalan yang mendasari.

Rancangan Python 2 jam: Pendekatan yang realistikRancangan Python 2 jam: Pendekatan yang realistikApr 11, 2025 am 12:04 AM

Anda boleh mempelajari konsep pengaturcaraan asas dan kemahiran Python dalam masa 2 jam. 1. Belajar Pembolehubah dan Jenis Data, 2.

Python: meneroka aplikasi utamanyaPython: meneroka aplikasi utamanyaApr 10, 2025 am 09:41 AM

Python digunakan secara meluas dalam bidang pembangunan web, sains data, pembelajaran mesin, automasi dan skrip. 1) Dalam pembangunan web, kerangka Django dan Flask memudahkan proses pembangunan. 2) Dalam bidang sains data dan pembelajaran mesin, numpy, panda, scikit-learn dan perpustakaan tensorflow memberikan sokongan yang kuat. 3) Dari segi automasi dan skrip, Python sesuai untuk tugas -tugas seperti ujian automatik dan pengurusan sistem.

Berapa banyak python yang boleh anda pelajari dalam 2 jam?Berapa banyak python yang boleh anda pelajari dalam 2 jam?Apr 09, 2025 pm 04:33 PM

Anda boleh mempelajari asas -asas Python dalam masa dua jam. 1. Belajar pembolehubah dan jenis data, 2. Struktur kawalan induk seperti jika pernyataan dan gelung, 3 memahami definisi dan penggunaan fungsi. Ini akan membantu anda mula menulis program python mudah.

Bagaimana Mengajar Asas Pengaturcaraan Pemula Komputer Dalam Kaedah Projek dan Masalah Dikemukakan Dalam masa 10 Jam?Bagaimana Mengajar Asas Pengaturcaraan Pemula Komputer Dalam Kaedah Projek dan Masalah Dikemukakan Dalam masa 10 Jam?Apr 02, 2025 am 07:18 AM

Bagaimana Mengajar Asas Pengaturcaraan Pemula Komputer Dalam masa 10 jam? Sekiranya anda hanya mempunyai 10 jam untuk mengajar pemula komputer beberapa pengetahuan pengaturcaraan, apa yang akan anda pilih untuk mengajar ...

Bagaimana untuk mengelakkan dikesan oleh penyemak imbas apabila menggunakan fiddler di mana-mana untuk membaca lelaki-dalam-tengah?Bagaimana untuk mengelakkan dikesan oleh penyemak imbas apabila menggunakan fiddler di mana-mana untuk membaca lelaki-dalam-tengah?Apr 02, 2025 am 07:15 AM

Cara mengelakkan dikesan semasa menggunakan fiddlerevery di mana untuk bacaan lelaki-dalam-pertengahan apabila anda menggunakan fiddlerevery di mana ...

Apa yang perlu saya lakukan jika modul '__builtin__' tidak dijumpai apabila memuatkan fail acar di Python 3.6?Apa yang perlu saya lakukan jika modul '__builtin__' tidak dijumpai apabila memuatkan fail acar di Python 3.6?Apr 02, 2025 am 07:12 AM

Memuatkan Fail Pickle di Python 3.6 Kesalahan Laporan Alam Sekitar: ModulenotFoundError: Nomodulenamed ...

See all articles

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
4 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌

Alat panas

MinGW - GNU Minimalis untuk Windows

MinGW - GNU Minimalis untuk Windows

Projek ini dalam proses untuk dipindahkan ke osdn.net/projects/mingw, anda boleh terus mengikuti kami di sana. MinGW: Port Windows asli bagi GNU Compiler Collection (GCC), perpustakaan import yang boleh diedarkan secara bebas dan fail pengepala untuk membina aplikasi Windows asli termasuk sambungan kepada masa jalan MSVC untuk menyokong fungsi C99. Semua perisian MinGW boleh dijalankan pada platform Windows 64-bit.

Versi Mac WebStorm

Versi Mac WebStorm

Alat pembangunan JavaScript yang berguna

SecLists

SecLists

SecLists ialah rakan penguji keselamatan muktamad. Ia ialah koleksi pelbagai jenis senarai yang kerap digunakan semasa penilaian keselamatan, semuanya di satu tempat. SecLists membantu menjadikan ujian keselamatan lebih cekap dan produktif dengan menyediakan semua senarai yang mungkin diperlukan oleh penguji keselamatan dengan mudah. Jenis senarai termasuk nama pengguna, kata laluan, URL, muatan kabur, corak data sensitif, cangkerang web dan banyak lagi. Penguji hanya boleh menarik repositori ini ke mesin ujian baharu dan dia akan mempunyai akses kepada setiap jenis senarai yang dia perlukan.

Dreamweaver Mac版

Dreamweaver Mac版

Alat pembangunan web visual

Pelayar Peperiksaan Selamat

Pelayar Peperiksaan Selamat

Pelayar Peperiksaan Selamat ialah persekitaran pelayar selamat untuk mengambil peperiksaan dalam talian dengan selamat. Perisian ini menukar mana-mana komputer menjadi stesen kerja yang selamat. Ia mengawal akses kepada mana-mana utiliti dan menghalang pelajar daripada menggunakan sumber yang tidak dibenarkan.