【Rede do computador】HTTP/HTTPS

protocolo de rede HTTP

Embora digamos que o protocolo da camada de aplicação é determinado por nossos programadores, na verdade, alguns grandes nomes definiram alguns protocolos da camada de aplicação prontos e muito úteis para nossa referência direta. HTTP (Hypertext Transfer agreement) é um deles

Entenda os protocolos de rede

O protocolo é uma espécie de "acordo". A interface do socket api, ao ler e escrever dados, é enviada e recebida na forma de "string". E se quisermos transmitir alguns "dados estruturados"?

Em primeiro lugar, podemos armazenar esses dados estruturados em uma estrutura. Ambas as partes da comunicação conhecem essa estrutura. Ao receber e enviar solicitações ou respostas, podemos usar a estrutura para receber e, assim, atingir o objetivo de transmitir dados estruturados. E como a estrutura é definida e quais são os membros internos da estrutura? Este é um acordo entre o cliente e o servidor antes da comunicação.A premissa da comunicação é que ambas as partes conheçam e estejam dispostas a cumprir este acordo.

calculadora simples online

Veja a nuvem de código para todos os detalhes do código

A utilização dessas duas estruturas é um contrato (protocolo) definido por nós mesmos, e tanto o cliente quanto o servidor que criamos devem respeitá-lo! Isso é chamado de protocolo personalizado

A calculadora de versão on-line no modo cs que escrevemos é essencialmente um serviço de rede da camada de aplicativo. O código de comunicação básico é escrito por nós mesmos. A serialização e a desserialização (a ser discutida posteriormente) são concluídas por meio de componentes, solicitações. o formato do resultado e também escrevemos a lógica de negócios nós mesmos.

Através desta versão simples da calculadora, podemos estabelecer uma compreensão preliminar das três camadas superiores do modelo OSI de sete camadas

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo de link anti-roubo, é recomendável salvar a imagem e carregá-la diretamente (img-WTyDpKFQ-1674359312023) (C:\Users\Lenovo\AppData\Roaming\Typora \typora-user-images\ imagem-20230117092635849.png)]

//请求结构体
typedef struct request{
    
     //请求结构体
    int x; 				//数字1	
    int y;				//数字2
    char op;			//运算符
}request_t;

//响应结构体
// response format 相应格式
typedef struct response{
    
    
    int sign;			//标志位,反应结果是否可靠
    int result; 		//结果
}response_t;

Parte do código de comunicação do servidor

// 服务器 
// 1.Read request
  request_t req;							  //创建请求结构体接收请求
  memset(&req, 0, sizeof(req));		
  ssize_t s = read(sock, &req, sizeof(req));  //将网络数据传输给请求结构体对象
  std::cout << "get a request, request size = " << sizeof(req) << std::endl;
  std::cout << s << " " << req.x << req.op << req.y << std::endl; 
  if (s == sizeof(req)){
    
    			
    // Read full request success 			 //若获取的请求完整
    // 2.prase request 						 //解析请求信息,构建响应结构体
    std::cout << "prase request" << std::endl;
    response_t resp{
    
    0 , 0};					 
    switch (req.op){
    
    						 //通过请求信息来构建响应
      case '+':
        resp.result = req.x + req.y;
        break;
      case '/':
        if (req.y == 0) resp.sign = 1;
        else resp.result = req.x / req.y;
        break;
      default:
        resp.sign = 3; // request method errno
        break;
    }
    // send response
    std::cout << "return response" << std::endl;
    write(sock, &resp, sizeof(resp));	 	 //将构建的响应发送给客户端
  }

Parte do código de comunicação do cliente

  // 客户端
  request_t req;						//从标准输入(客户)得到数据保存到结构体中
  cout << "Please Enter Date One# ";
  cin >> req.x;
  cout << "Please Enter Date Two# ";
  cin >> req.y;
  cout << "Please Enter Operator";
  cin >> req.op;

  write(sock, &req, sizeof(req));	 	//将结构体发送给服务器
  response_t resp;						//创建响应结构体接收服务器响应
  ssize_t s = read(sock, &resp, sizeof(resp)); //读取响应内容打印结果
  if (s == sizeof(resp)){
    
    
    if (resp.sign == 1){
    
    
      std::cout << "除零错误" << std::endl;
    }
    else if (resp.sign == 3){
    
    
      std::cout << "非法运算符" << std::endl;
    }
    else {
    
    
      std::cout << "result = " << resp.result << std::endl;
    }
  }

Por meio do código acima, de fato concluímos a transmissão de dados estruturados em rede por meio do protocolo definido por nós mesmos usando a estrutura, mas esse método tem desvantagens muito óbvias. Em primeiro lugar, devemos garantir que o alinhamento de memória do cliente e do servidor seja o mesmo . Em segundo lugar, uma vez que o servidor seja atualizado e a estrutura transmitida seja modificada, todos os clientes anteriores não poderão usá-lo , porque os formatos das duas estruturas são diferentes, então não há esperança de que os dados transmitidos possam ser retirados como estão. Além disso, o tamanho de alguns dados em muitos cenários não é fixo , como no chat do WeChat, como saber o tamanho de uma mensagem enviada por uma pessoa e quanto espaço devemos abrir para a estrutura da mensagem? ? Se for muito grande, os recursos de rede serão desperdiçados, se for muito pequeno, pode demorar um pouco mais e ocorrerão problemas como truncamento ou caracteres ilegíveis

Para resolver os problemas acima, os programadores anteriores propuseram serialização e desserialização

Serialização e desserialização

Quando um host deseja enviar dados para a rede, ele serializa os dados e os transmite para a rede. Depois que um host deseja ler dados da rede, ele precisa desserializar os dados na rede

JSON é uma ferramenta de serialização e desserialização comumente usada em nosso desenvolvimento diário

sudo yum install -y jsoncpp-devel //安装json

dados de transferência JSON

Serialização JSON
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

typedef struct request{
    
    
    int x;
    int y;
    char op;
}request_t;

int main(){
    
    
    request_t req{
    
    10, 20, '*'};
    //序列化过程
    Json::Value root; //可以承装任何对象,json是一种kv式的序列化方案
    root["datax"] = req.x;
    root["datay"] = req.y;
    root["operator"] = req.op;

    // Json::StyledWriter writer;
    Json::FastWriter writer;
    writer.write(root);
    std::string json_string = writer.write(root);
    std::cout << json_string << std::cout;
    return 0;
}

Json::StyledWriter类型对象构建的json_string 
    
{
    
    "datax":10,"datay":20,"operator":42}

Json::FastWriter 类型对象构建的json_string
    
{
    
    
   "datax" : 10,
   "datay" : 20,
   "operator" : 42
}
[clx@VM-20-6-centos JsonTest]$ ldd a.out
        linux-vdso.so.1 =>  (0x00007fffddfee000)
        /$LIB/libonion.so => /lib64/libonion.so (0x00007f80236f2000)
        libjsoncpp.so.0 => /lib64/libjsoncpp.so.0 (0x00007f80233a2000) // 这就是第三方组件,也就是一个动态库
        libstdc++.so.6 => /home/clx/.VimForCpp/vim/bundle/YCM.so/el7.x86_64/libstdc++.so.6 (0x00007f8023021000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f8022d1f000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f8022b09000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f802273b000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f8022537000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f80235d9000)
desserialização JSON
int main(){
    
    
    // 反序列化
    std::string json_string = R"({"datax":10, "datay":20, "operator":42})";//R()可以防止内部字符部分字符被转义
    Json::Reader reader; //使用Json::Reader类型对象反序列化 序列化数据,放入万能对象root中
    
    Json::Value root;
    reader.parse(json_string, root);
    request_t req;
    req.x = root["datax"].asInt();//root使用key来查找value数据,并使用asInt()函数转化成对应类型
    req.y = root["datay"].asInt();
    req.op = root["operator"].asUInt();
    std::cout << req.x << " " << req.op << " "<< req.y << std::endl;
    return 0; 
}

Otimize a calculadora com JSON

1. Use JSON para serializar e desserializar as estruturas de solicitação e resposta, respectivamente

std::string SerializeRequest(const request_t &req){
    
    
    Json::Value root;
    root["datax"] = req.x;
    root["datay"] = req.y;
    root["operator"] = req.op;

    Json::FastWriter writer;
    std::string json_string = writer.write(root);
    return json_string;
}

void DeserializeRequest(const std::string &json_string, request_t &out){
    
    
    Json::Reader reader;
    
    Json::Value root;
    reader.parse(json_string, root);
    out.x = root["datax"].asInt();
    out.y = root["datay"].asInt();
    out.op = root["operator"].asUInt();
}

std::string SerializeResponse(const response_t &resp){
    
    
    Json::Value root;
    root["sign"] = resp.sign;
    root["result"] = resp.result;

    Json::FastWriter writer;
    std::string json_string = writer.write(root);
    return json_string;
}

void DeserializeResponse(const std::string &json_string, response_t &out){
    
    
    Json::Reader reader;
    
    Json::Value root;
    reader.parse(json_string, root);
    out.sign = root["sign"].asInt();
    out.result = root["result"].asInt();
}

2. Use strings JSON para transmitir dados dentro da rede

  //1.Method2 ReadRequest 从网络中读取Json字符串
  char buffer[1024] = {
    
    0};
  ssize_t s = read(sock, buffer, sizeof(buffer) - 1);
  buffer[s] = 0;
  if (s > 0){
    
    
    request_t req;
    DeserializeRequest(buffer, req);
      
  // send response 将结构化数据进行序列化后再发送
    std::string json_string = SerializeResponse(resp);
    write(sock, json_string.c_str(), json_string.size());
    std::cout << "return response successs" << std::endl;

Entenda formalmente o protocolo HTTP

Embora digamos que o protocolo da camada de aplicação é determinado por nossos programadores, na verdade, alguns caras grandes definiram alguns protocolos da camada de aplicação prontos e muito fáceis de usar para nossa referência direta. **HTTP (super Text Transfer Protocol) ** é um dos

O protocolo HTTP é essencialmente o mesmo que a calculadora de rede que acabamos de escrever. É um protocolo de camada de aplicativo. Ele também implementa três etapas em nossa calculadora de rede: 1. Comunicação de rede 2. Serialização e desserialização 3. Detalhes do protocolo

Compreensão básica de URL

Normalmente, o que chamamos de site é na verdade uma URL

As fotos e vídeos que solicitamos são chamados de recursos e esses recursos são armazenados em uma máquina Linux na rede. IP + Porta identifica exclusivamente um processo, mas não pode identificar exclusivamente um recurso. No entanto, os sistemas operacionais tradicionais armazenam recursos em arquivos.Para um único sistema Linux, a maneira de identificar recursos exclusivos é por meio de caminhos.

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo anti-leeching, é recomendável salvar a imagem e carregá-la diretamente (img-4cJ4B5LL-1674359312024) (C:\Users\Lenovo\AppData\Roaming\Typora\ typora-user-images\ imagem-20230117095522126.png)]

IP + PortIdentifique exclusivamente um processo (o IP geralmente é apresentado como um nome de domínio)

IP+Linux路径Um recurso de rede pode ser identificado exclusivamente (o caminho pode ser confirmado pelo nome do diretório +/)

Protocolos de rede comuns, como HTTP, têm seus próprios números de porta de servidor especificados , o que é como ligar para a polícia 110. Todos os chineses sabem que 110 é o número de chamada da polícia. E todos aqueles que estudaram programadores de rede também sabem que HTTP corresponde à porta número 80, então esse número de porta pode ser omitido em muitos casos

urlencode e urldecode

Caracteres como / ?: foram entendidos por url como significados especiais. Portanto, esses caracteres não podem aparecer aleatoriamente. Por exemplo, se um parâmetro precisar conter esses caracteres especiais, os caracteres especiais devem ser escapados primeiro.

As regras de escape são as seguintes: Converta os caracteres a serem transcodificados em hexadecimal e, da direita para a esquerda, pegue 4 dígitos (menos de 4 dígitos e processe-os diretamente), faça um dígito para cada 2 dígitos, adicione % na frente , e codifique-o como formato % XY

Por exemplo, pesquisamos por tradução e C++ no Baidu, respectivamente
insira a descrição da imagem aqui
insira a descrição da imagem aqui

Observando a URL acima, podemos verificar que existe um campo wd para transmitir nossas palavras-chave de busca, a tradução não mudou na URL e os dois sinais de mais em C++ são escapados por causa de caracteres como + É entendido por url como um significado especial, e será escapado antes da transmissão

Podemos usar esta ferramenta de escape para escapar de nossa própria string e ver sua forma na URL

formato do protocolo HTTP

Seja uma solicitação ou uma resposta, http constrói a solicitação ou resposta em unidades de linhas (\n)! Quer seja um pedido ou uma resposta, é quase composto por 3 ou 4 partes

Como entender o comportamento online de usuários comuns 1. Obtenha os recursos que deseja do servidor de destino 2. Carregue seus dados no servidor de destino

solicitação HTTP

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo anti-leeching, é recomendável salvar a imagem e carregá-la diretamente (img-jbw4HkaW-1674359312025) (C:\Users\Lenovo\AppData\Roaming\Typora\ typora-user-images\ imagem-20230117103231286.png)]

A primeira parte da linha de solicitação (a primeira linha) consiste em método de solicitação + url (o conteúdo após a remoção do nome de domínio) + versão do protocolo http + \n

A segunda parte é o cabeçalho da solicitação (Header), um par chave-valor separado por dois pontos; cada grupo de atributos é separado por \n; uma linha em branco indica o final da parte do cabeçalho

A terceira parte está em branco\n

A quarta parte do corpo da solicitação (corpo) (se houver) são os dados enviados pelo usuário. O corpo da solicitação pode ser uma string vazia. Se o corpo existir, haverá um atributo Content-Length no cabeçalho para identificar o comprimento do corpo

As três primeiras partes são chamadas de cabeçalhos de solicitação HTTP e a quarta parte se torna a carga útil HTTP

Resposta HTTP

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo anti-leeching, é recomendável salvar a imagem e carregá-la diretamente (img-PsDLkPxb-1674359312026) (C:\Users\Lenovo\AppData\Roaming\Typora\ typora-user-images\ imagem-20230117104512531.png)]

A primeira parte da linha de status (a primeira linha) é descrita pela versão do protocolo http + código de status + código de status

A segunda parte é o cabeçalho da solicitação (Header), um par chave-valor separado por dois pontos; cada grupo de atributos é separado por \n; uma linha em branco indica o final da parte do cabeçalho

A terceira parte está em branco\n

A quarta parte é o corpo da resposta (Body) (se houver) Os dados enviados pelo usuário, o corpo da resposta pode ser uma string vazia. Se o corpo existir, haverá um atributo Content-Length no cabeçalho para identificar o comprimento do corpo da resposta

As três primeiras partes são chamadas de cabeçalhos de resposta HTTP e a quarta parte se torna a carga útil HTTP

pensar:

1. Como descompactar respostas ou solicitações HTTP e como compartilhá-las

2. Como a solicitação ou resposta HTTP é lida? enviar como string

3. Como a solicitação HTTP é enviada? ler como string

4. Como a solicitação http e a resposta http são tratadas? corda

Como descompactar: ​​tratamos a solicitação e a resposta como uma string grande, e a linha em branco é um caractere especial no protocolo HTTP. Use uma linha em branco para distinguir o cabeçalho HTTP da carga útil. Quando lemos os dados linha por linha, quando não há dados nesta linha e apenas \n, sabemos que o cabeçalho HTTP foi lido e a próxima parte é a carga útil

Como compartilhar: Isso não é resolvido pelo http, mas por códigos de aplicativos específicos. O HTTP precisa de uma interface para ajudar a camada superior a obter parâmetros

método HTTP

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo de link anti-roubo, é recomendável salvar a imagem e carregá-la diretamente (img-LW0qNJhh-1674359312026) (C:\Users\Lenovo\AppData\Roaming\Typora \typora-user-images\ imagem-20230118101413117.png)]

O suporte ao protocolo não significa que o servidor oferece suporte a este método, o servidor oferecerá suporte a vários métodos de acordo com sua própria situação

Códigos de status HTTP comuns

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo de link anti-roubo, é recomendável salvar a imagem e carregá-la diretamente (img-kz8V9iYA-1674359312026) (C:\Users\Lenovo\AppData\Roaming\Typora \typora-user-images\ imagem-20230118100201726.png)]

Os códigos de status mais comuns, como 200 (OK), 404 (Não encontrado), 403 (Permissão proibida é muito baixa para acessar), 301 (redirecionamento permanente), 302 ou 307 (Redirecionamento, redirecionamento temporário), 504 (Gateway inválido).

Redirecionamento permanente: Por exemplo, se um site for atualizado e a URL também for atualizada, ele definirá um redirecionamento permanente na URL original, para que você possa pular para a nova página quando visitar a URL antiga

Redirecionamento temporário: por exemplo, ao fazer um pedido no Meituan, ele pulará para a interface de pedido do Meituan e voltará automaticamente para a interface original depois que fizermos o pedido

A camada de aplicação exige que as pessoas participem, e o nível das pessoas é desigual. Muitas pessoas não sabem como usar o código de status http e, como existem tantos navegadores, o suporte de todos para o código de status não é particularmente bom Às vezes você escreve um erro O código de status ainda pode ser exibido. Portanto, agora o código de status 404 não tem significado de orientação para o navegador, e o navegador apenas exibe sua página da Web normalmente

Cabeçalho comum HTTP

Content-Type: 数据类型(text/html等)
Content-Length: Body的长度
Host: 客户端告知服务器, 所请求的资源是在哪个主机的哪个端口上;
User-Agent: 声明用户的操作系统和浏览器版本信息;
referer: 当前页面是从哪个页面跳转过来的;
location: 搭配3xx状态码使用, 告诉客户端接下来要去哪里访问;
Cookie: 用于在客户端存储少量信息. 通常用于实现会话(session)的功能;
Conection: 1.0只有短链接,HTTP1.1版本之后支持长链接

Conection: keep-alivelink longo

Todos os experimentos que fizemos antes foram para solicitar e responder a links de desconexão, mas há muitos recursos em um servidor, e uma grande página da Web é composta de muitos recursos, e cada recurso precisa iniciar uma solicitação http. No entanto, http/1.1 lançou uma versão de link longo, e o link entre as duas partes é estabelecido apenas uma vez e o link é fechado após a conclusão de todas as interações de recursos. Para atingir o objetivo de melhorar a eficiência, reduzindo o estabelecimento frequente da irmã TCP Lina

Crie um servidor HTTP simples

Design de página de front-end simples

Este site contém um tutorial simples de front-end e Mina HTML w3cschool , fiz uma interface HTML de página inicial simples por meio do formulário deste site

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <h3>hello net</h3> 
        <h5>hello 我是表单</h5>
        <from action="/a" method = "POST">
            姓名:<input type="text" name="name"><br/>
            密码:<input type="password" name="passwd"><br/>
            <input type="submit" value="登录"> <br/>
        </from>
    </body>
</html>

construção do servidor HTTP

//这里使用了专门的网络写入读取接口
ssize_t recv(int sockfd, void *buf, size_t len, int flags);  
ssize_t send(int sockfd, const void *buf, size_t len, int flags);

Este grupo de interfaces é exatamente igual às nossas interfaces de leitura e escrita, falgsbastando colocar o último parâmetro em 0. Para outras utilizações, pode-se utilizar o man recvcomando para visualizar o documento.

#include "Sock.hpp"
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fstream>

#define WWWROOT "./wwwroot/"    //根目录
#define HOME_PAGE "index.html"	//首页

void Usage(std::string proc){
    
    
    std::cout << "Usage " << proc << " port " << std::endl; 
}

void* HandlerHttpRequest(void* args){
    
    
    int sock = *(int*)args;
    delete (int*)args;
    
    pthread_detach(pthread_self());
#define SIZE 1024 * 10
    char buffer[SIZE];
    memset(buffer, 0, SIZE);
    ssize_t s = recv(sock, buffer, sizeof(buffer) - 1, 0);
    if (s > 0){
    
    
        buffer[s] = 0;
        std::cout << buffer << std::endl;                 //查看浏览器发来的HTTP请求
        //构建HTTP响应
        // std::string http_response = "http/1.0 200 OK\n";  //构建响应状态行
        // http_response += "Content-Type: text/plain\n";    //正文的属性
        // http_response += "\n";                            //空行
        // http_response += "hello net!";                    //正文  

        std::string html_file = WWWROOT;
        html_file += HOME_PAGE;
        // 返回的时候不仅仅是返回正文网页信息,而是要包括http请求
        std::string http_response = "http/1.0 200 OK\n";
        // 正文部分的数据类型
        http_response += "Content-Type: text/html; charset=utf8\n";
        struct stat st;
        stat(html_file.c_str(), &st);
        http_response += "Content-Length: ";
        http_response += std::to_string(st.st_size);
        http_response += "\n";
        http_response += "\n";
        //std::cout << http_response << std::endl;
        //响应正文
        std::ifstream in(html_file);
        if (!in.is_open()){
    
    
            std::cerr << "open html error!" << std::endl;
        }
        else {
    
    
            std::cout << "open success" << std::endl;
            std::string content;
            std::string line;
            while (std::getline(in, line)){
    
    
                content += line;
            }
            //std::cout << content << std::endl;
            http_response += content;
            //std::cout << http_response << std::endl;
        }
        send(sock, http_response.c_str(), http_response.size(), 0);
    }
    close(sock);
    return nullptr;
}
int main(int argc, char* argv[]){
    
    
    if (argc != 2) {
    
     Usage(argv[0]); return 1;}
    uint16_t port = atoi(argv[1]);
    int listen_sock = Sock::Socket();
    Sock::Bind(listen_sock, port);
    Sock::Listen(listen_sock);

    for ( ; ; ){
    
    
        int sock = Sock::Accept(listen_sock);
        if (sock > 0){
    
    
            pthread_t tid;
            int *psock = new int(sock);
            pthread_create(&tid, nullptr, HandlerHttpRequest, (void*)psock);
        }
    }
}

Aqui iniciamos o servidor HTTP com a porta número 9090. Embora o servidor HTTP geralmente use a porta 80, este é apenas um hábito comum, não significa que o servidor HTTP não possa usar outros números de porta.

Execute nosso programa para receber solicitações HTTP da rede. Podemos usar o navegador para enviar solicitações ao nosso programa. Só precisamos inserir nosso no navegador e podemos 公网IP:端口号ver que o navegador nos envia A solicitação HTTP recebida é a seguinte

GET / HTTP/1.1                //请求行
Host: 101.43.252.201:8888	  //请求报头
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
							 //空行 到此HTTP请求报头结束,这个请求没有正文
GET / HTTP/1.1                //请求行

Você pode ver que o método de solicitação é seguido por um /diretório raiz da Web. Geralmente, iniciamos uma solicitação para obter um recurso específico em um servidor. Podemos identificar exclusivamente um recurso por IP + caminho. Se o caminho solicitado /for Queremos solicitar o página inicial do site

Tipos comuns de Content-Type podem ser vistos no blog deste blogueiro, que é bem completo

Como julgar que terminamos de ler a parte do cabeçalho? ? ler linha em branco

Depois de ler a parte do cabeçalho, podemos extrair corretamente vários atributos da parte do cabeçalho, incluindo Content-Length

Determine se há algum texto após a linha em branco, está relacionado ao método de solicitação

Se for o texto, como garantir que todo o texto seja lido e os dados do próximo HTTP não sejam lidos? ?
Se houver um corpo, a parte do cabeçalho consiste em um atributo: Content-Length: len, indicando de quantos bytes o corpo consiste

Métodos GET e POST

Método GET: Também conhecido como método de aquisição, é o método mais comumente usado. Por padrão, todas as páginas da web são obtidas pelo método GET, mas se você quiser usar o método GET para enviar parâmetros, os parâmetros serão emendados ​​​através do URL e enviado ao servidor.

Método POST: Também conhecido como método push, é um método comum para enviar parâmetros, mas se enviar parâmetros, geralmente é enviado pela parte do corpo, mas não se esqueça que Content-Length: XXX indica o comprimento do corpo

POST vs GET

A localização do envio do parâmetro é diferente e o método POST é mais privado (privado! = seguro, seguro = criptografado) e não será ecoado na caixa de URL do navegador! O método get não é privado e irá ecoar informações importantes para a caixa de entrada de url, aumentando o risco de ser roubado

GET é passado pela URL e a URL tem um limite de tamanho! Especificamente relacionado ao navegador. O método POST é passado pela parte do corpo e o tamanho geral não é limitado

Se os parâmetros enviados não forem sensíveis e o número for muito pequeno, você pode usar o método GET; caso contrário, use o método POST

Cookies e Sessões

Na vida cotidiana, descobrimos que, quando várias páginas saltam, a essência é que o site ainda me conhece depois de fazer várias solicitações http. Por exemplo, sou um grande membro da estação B, não importa como eu navegue pelos vídeos na estação B, ele não me deixa fazer login novamente, mas o protocolo HTTP é um protocolo sem estado, ele só se preocupa se essa solicitação foi bem-sucedida, e as solicitações anteriores não mantêm nenhum registro

Deixar o site me conhecer não é um problema a ser resolvido pelo próprio protocolo HTTP, o HTTP pode fornecer algum suporte técnico para garantir que o site tenha uma função de retenção de sessão. Um cookie é uma ferramenta de gerenciamento de sessão

  1. Navegador: Um cookie é na verdade um arquivo que armazena as informações privadas de nosso usuário
  2. Protocolo http: uma vez que o site corresponda a um cookie, quando qualquer solicitação for iniciada, as informações do cookie serão automaticamente transportadas na solicitação
//Set-Cookie: 服务器向浏览器设置一个cookie
http_response += "Set-Cookie: id=1111111111\n"; 
http_response += "Set-Cookie: password=2222\n"; 

Adicionamos duas linhas à resposta HTTP, usamos o navegador para enviar uma solicitação ao servidor e adicionamos o atributo Set-Cookie ao cabeçalho de resposta do servidor para definir o arquivo de cookie do navegador

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo de link anti-roubo, é recomendável salvar a imagem e carregá-la diretamente (img-Psmt84o1-1674359312027) (C:\Users\Lenovo\AppData\Roaming\Typora \typora-user-images\ imagem-20230118193436875.png)]

Use o navegador para enviar a solicitação novamente e você verá que a solicitação contém informações de cookies

GET / HTTP/1.1
Host: 101.43.252.201:8889
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: id=1111111111; password=2222 //Cookie信息

Formato de armazenamento do arquivo de cookie do navegador: 1. versão do arquivo 2. versão da memória

A diferença é que depois de fazer login em um site, fechar o navegador e abrir o site, se a página da web conectada ainda o reconhece, se você ainda a conhece, ela é salva na versão do arquivo e, se você não Se você não sabe, ele é salvo na versão de memória.

Portanto, se outra pessoa roubar nosso arquivo de cookie, outras pessoas poderão acessar recursos específicos com minha autenticação de identidade.Se nosso nome de usuário e senha forem salvos, será muito ruim . Então, simplesmente usar cookies tem certos riscos de segurança, então Session sai, mas usar Session não significa que não usamos cookies

A ideia central da Session: salvar as informações privadas do usuário no lado do servidor

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo anti-leeching, é recomendável salvar a imagem e carregá-la diretamente (img-uEErO39O-1674359312028) (C:\Users\Lenovo\AppData\Roaming\Typora\ typora-user-images\ image-20230118200516017.png)]

O navegador envia as informações privadas para o servidor e o servidor autentica as informações privadas, cria um arquivo de sessão e o salva no servidor, então gera um session_id exclusivo por meio do arquivo de sessão e define o session_id para o arquivo de cookie no navegador . Quando fizermos login novamente, o navegador carregará automaticamente as informações do cookie (session_id) para enviar a solicitação e o servidor subsequente ainda poderá reconhecer o cliente

O navegador do usuário não salva mais as informações privadas, portanto, mesmo que as informações do cookie do usuário vazem, outras pessoas não obterão o nome de usuário e a senha (informações privadas), mas o risco de vazamento do arquivo do cookie ainda existe e outros ainda podem usar o cookie arquivo para nos visitar Os sites visitados , porque o arquivo de cookie está no computador do usuário e o usuário não tem conhecimento de proteção.

** Para esses riscos, as empresas de Internet também adotaram algumas medidas de defesa derivadas, como fazer login de outro local e inserir novamente a senha da conta. **Por exemplo, existem alguns grupos ilegais de fraude de telecomunicações em Mianmar. Eles roubaram a conta QQ de um pequinês e fizeram login em Mianmar. O IP de login desta conta QQ ainda estava em Pequim um minuto atrás, mas agora o IP de login é exibido como Myanmar O sistema detecta Se houver uma exceção, as medidas de defesa serão ativadas e você será solicitado a inserir novamente a senha da conta. Nesse caso, o sistema determinará automaticamente que a conta foi roubada e descartará o arquivo de sessão original. Se você digitar novamente a senha da conta, o sistema gerará novamente um novo arquivo de sessão e session_id para você.

HTTPS

camada de criptografia e descriptografia

Todos os sites que podemos nomear usam o protocolo HTTPS. Qual é a diferença entre o protocolo **HTTP e HTTPS? ? criptografia**

HTTPS = HTTP + TLS/SSL (criptografia de dados e camada de descriptografia)

A camada de criptografia e descriptografia está na parte inferior da camada de protocolo HTTP. O HTTP primeiro acessa as interfaces da camada de segurança TLS e SSL e, em seguida, a interface da camada de segurança chama a interface de chamada do sistema, interface de soquete e os dados serão criptografados/descriptografados após sendo lido pela interface de chamada do sistema. Portanto, HTTPS é o protocolo HTTP mais uma camada de criptografia e descriptografia, e essas duas camadas são chamadas coletivamente de HTTPS . E, na maioria dos casos, apenas os dados do usuário (payload) serão criptografados, outros dados não são necessários

dois métodos de criptografia

1. Criptografia simétrica, chave (apenas uma) X

Use a chave X para criptografar e também use a chave X para descriptografar, por exemplo:

data ^ X = result; // 加密
result ^ X = data; // 解密

2. A criptografia assimétrica possui um par de chaves: chave pública e chave privada

Ele pode ser criptografado com a chave pública, mas apenas descriptografado com a chave privada ou criptografado com a chave privada e descriptografado apenas com a chave pública. O clássico algoritmo de criptografia assimétrica RSA de um modo geral, a chave pública é aberta para o mundo e a chave privada deve ser mantida em sigilo!

Como confirmar se o texto permanece intacto após ser transmitido pela rede e detectar se foi adulterado

Podemos usar o algoritmo Hash hash para processar o texto para formar uma sequência de cadeia única de comprimento fixo chamada resumo de dados ou impressão digital de dados. (Algoritmo de hash hash, desde que haja apenas uma diferença de pontuação no texto, ele também gerará um resultado de hash muito diferente) e, em seguida, execute o processamento do algoritmo de criptografia no resumo de dados para gerar uma assinatura de dados. Envie a assinatura de dados junto com o texto para outro host na rede. Depois de receber os dados, a outra extremidade descriptografa a assinatura de dados para obter a impressão digital de dados 1 e, em seguida, processa o texto com o algoritmo Hash hash para gerar a impressão digital de dados 2. Se as duas impressões digitais de dados forem iguais, o texto não foi adulterado

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo anti-leeching, é recomendável salvar a imagem e carregá-la diretamente (img-nVrWi6b1-1674359312028) (C:\Users\Lenovo\AppData\Roaming\Typora\ typora-user-images\ imagem-20230118215816713.png)]

Aplicações Práticas de Criptografia

Então, em nossa vida diária, usamos criptografia simétrica ou criptografia assimétrica? ?

Se usarmos criptografia simétrica, como devemos implantar a chave em ambos os servidores? ? Podemos resolver isso pré-instalando todas as chaves simétricas na máquina com antecedência, mas o custo da pré-instalação é muito alto.Se cada servidor exigir que instalemos manualmente a chave, isso é muito problemático? Posso usar a Internet para baixar? O download é igual à comunicação de rede, então a chave de download precisa ser criptografada? ? Mesmo que ambas as partes tenham uma chave, como devem negociar qual chave usar? ? Negociar a chave pela primeira vez não tem absolutamente nenhuma criptografia . Portanto, usar diretamente a criptografia simétrica é realmente inseguro

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo anti-leeching, é recomendável salvar a imagem e carregá-la diretamente (img-NGsbpN6t-1674359312029) (C:\Users\Lenovo\AppData\Roaming\Typora\ typora-user-images\ imagem-20230122095057153.png)]

Se for usada criptografia assimétrica, geralmente são usados ​​dois pares de chaves assimétricas para garantir a segurança da comunicação. Tanto o cliente quanto o servidor possuem sua própria chave pública e chave privada.Durante a fase de negociação da chave pública, o servidor e o cliente enviam a chave pública entre si (os dados não são criptografados). Em seguida, entre no estágio de comunicação, os dados do cliente são criptografados com a chave pública S de S e enviados para o servidor, e então o servidor usa sua própria chave privada S` para descriptografar para obter os dados. Da mesma forma, o servidor criptografa a resposta usando a chave pública C do cliente e, em seguida, transmite os dados criptografados para o cliente, e o cliente os descriptografa com sua própria chave privada para obter os dados de resposta . Um par de chaves garante a segurança da comunicação em uma direção , mas qualquer método de criptografia assimétrica No entanto, existe o risco de roubo ilegal e o algoritmo de criptografia assimétrica é particularmente demorado e ineficiente

Esquemas assimétricos + simétricos usados ​​na vida real

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo anti-leeching, é recomendável salvar a imagem e carregá-la diretamente (img-UGyZLgUB-1674359312029) (C:\Users\Lenovo\AppData\Roaming\Typora\ typora-user-images\ imagem-20230122100427830.png)]

Estágio de chave de negociação: o servidor envia sua própria chave pública S (não criptografada) diretamente ao cliente, o cliente gera automaticamente uma chave X criptografada simetricamente, criptografa-a com a chave pública S e a envia ao servidor e o servidor usa sua própria chave privada S` para descriptografar , a chave simétrica X é obtida
Fase de comunicação: Tanto o servidor quanto o cliente conhecem a chave simétrica X e as duas partes se comunicam por meio da chave simétrica X

ataque man-in-the-middle

No link de rede, pode haver um man-in-the-middle para espionar e modificar nossos dados a qualquer momento. Quando o servidor e o cliente estão negociando chaves, eles podem receber ataques man-in-the-middle

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo de link anti-roubo, é recomendável salvar a imagem e carregá-la diretamente (img-AqjTDN20-1674359312029) (C:\Users\Lenovo\AppData\Roaming\Typora \typora-user-images\ imagem-20230122102008467.png)]

O intermediário intercepta a chave pública não criptografada S enviada pelo servidor ao cliente, modifica-a em sua própria chave pública M e a envia ao cliente. O cliente gera automaticamente uma chave simétrica X e criptografa X com a pública M chave e a envia para o servidor. Neste momento, mesmo que o servidor obtenha os dados X criptografados, ele não pode concluir a descriptografia, porque o servidor não possui M` . Se as informações X criptografadas forem interceptadas ou espiadas novamente pelo intermediário, ele poderá usar a chave privada para descriptografar e obter a chave simétrica X. Dessa forma, o intermediário estabelece uma comunicação com o cliente com base na chave simétrica X, e a resposta recebida pelo usuário é alterada de construída pelo servidor para uma construída pelo intermediário, e os dados do usuário são totalmente vazados.

Problema essencial: o cliente não consegue determinar se a mensagem de negociação da chave é enviada por um servidor legítimo

autoridade certificadora CA

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo anti-leeching, é recomendável salvar a imagem e carregá-la diretamente (img-2V877F6T-1674359312030) (C:\Users\Lenovo\AppData\Roaming\Typora\ typora-user-images\ imagem-20230122114734557.png)]

Desde que um provedor de serviços seja certificado por uma organização autorizada, a organização é legal. A organização CA é a autoridade de certificação autorizada na rede (ela também possui sua própria chave pública e chave privada)

O provedor de serviços deve fornecer suas próprias informações básicas (como: nome de domínio, chave pública, etc.) para solicitar um certificado de CA, e a instituição de CA criará um certificado com base nessas informações. As informações básicas da empresa são um pedaço de texto, e a organização da CA usará dados de hash hash para gerar impressões digitais de dados e, em seguida, **criptografar com a chave privada da organização da CA (importante! Importante! Importante!)** para gerar a assinatura digital da empresa, em seguida, construir o certificado e emiti-lo para o provedor de serviços legítimo

[Falha na transferência da imagem do link externo, o site de origem pode ter um mecanismo anti-leeching, é recomendável salvar a imagem e carregá-la diretamente (img-yYKZj5xz-1674359312030) (C:\Users\Lenovo\AppData\Roaming\Typora\ typora-user-images\ imagem-20230122112048895.png)]

Certificado: A assinatura digital gerada pela organização da CA para a empresa + a empresa fornece as informações básicas usadas para solicitar o certificado

Portanto, durante a fase de negociação de chaves entre o servidor e o cliente, o servidor só precisa enviar o certificado da CA para o cliente, pois as informações básicas do empreendimento no certificado contém a chave pública S do servidor. Depois de receber o certificado, o cliente usa a chave pública da organização da CA para descriptografar a assinatura de dados e, em seguida, faz um hash das informações básicas da empresa para comparar se as duas impressões digitais de dados são iguais. Se forem iguais, significa que a fonte de dados é legal e prossiga para a próxima etapa de operação.

Nota: O cliente usa a chave pública da organização CA para descriptografar a assinatura de dados. Como o cliente conhece a chave pública da organização CA? ?

Geralmente, é integrado. Quando baixamos o navegador, ele nos ajuda automaticamente a criar a chave pública da organização da CA. Além disso, não existe apenas uma instituição de CA. Se a empresa C fornecer um certificado de CA ao servidor de uma empresa, e a empresa A confiar na empresa B e a empresa B confiar na empresa C, isso significa que esta empresa é confiável tanto para ABC quanto para ABC. .

Uma pequena parte é que ao acessar a URL, o navegador pode solicitar que o usuário instale

Então, o intermediário pode interceptar as informações do seu certificado? ? claro que pode.

Mas um homem intermediário pode modificar a chave pública no certificado? ? Absolutamente não, porque se as informações básicas da empresa forem modificadas, a impressão digital de dados gerada será diferente da original. Desde que o cliente descriptografe a assinatura de dados e faça o hash das informações modificadas, pode-se descobrir que a impressão digital é diferente e os dados foram modificados.

Ele pode substituir as informações de chave pública da empresa e substituir a assinatura de dados? ? Não, porque a assinatura de dados é criptografada pela chave privada da organização CA, e o intermediário nunca saberá as informações da chave privada da organização CA. Se você usar sua própria chave privada para criptografar e gerar uma assinatura de dados, não poderá usar a chave pública da organização da CA para descriptografá-la.

E se o intermediário também for um servidor legal e tiver seu próprio certificado CA? ? O certificado CA não contém apenas a chave pública da empresa, mas também contém informações como o nome de domínio. O cliente envia claramente uma solicitação para www.baidu.com, mas a resposta é na verdade www.qq.com, o que torna você muito desconfortável. Razoavelmente, o armazenamento do certificado impede que o intermediário modifique os dados enviados pelo servidor ao cliente e, uma vez modificado, será detectado

A agência CA usa a chave privada para gerar assinaturas de dados, o que evita com sucesso que o intermediário modifique os dados de informações do servidor e represente o servidor para se comunicar com o cliente. No entanto, o intermediário também conhece a chave pública da organização CA e também conhece a chave pública do servidor. A chave simétrica X dados para descriptografar. Portanto, ele ainda conhece o conteúdo de nossa comunicação na web, mas não pode modificá-lo

Descriptografia, como o cliente conhece a chave pública da organização da CA? ?

Geralmente, é integrado. Quando baixamos o navegador, ele nos ajuda automaticamente a criar a chave pública da organização da CA. Além disso, não existe apenas uma instituição de CA. Se a empresa C fornecer um certificado de CA ao servidor de uma empresa, e a empresa A confiar na empresa B e a empresa B confiar na empresa C, isso significa que esta empresa é confiável tanto para ABC quanto para ABC. .

Uma pequena parte é que ao acessar a URL, o navegador pode solicitar que o usuário instale

Então, o intermediário pode interceptar as informações do seu certificado? ? claro que pode.

Mas um homem intermediário pode modificar a chave pública no certificado? ? Absolutamente não, porque se as informações básicas da empresa forem modificadas, a impressão digital de dados gerada será diferente da original. Desde que o cliente descriptografe a assinatura de dados e faça o hash das informações modificadas, pode-se descobrir que a impressão digital é diferente e os dados foram modificados.

Ele pode substituir as informações de chave pública da empresa e substituir a assinatura de dados? ? Não, porque a assinatura de dados é criptografada pela chave privada da organização CA, e o intermediário nunca saberá as informações da chave privada da organização CA. Se você usar sua própria chave privada para criptografar e gerar uma assinatura de dados, não poderá usar a chave pública da organização da CA para descriptografá-la.

E se o intermediário também for um servidor legal e tiver seu próprio certificado CA? ? O certificado CA não contém apenas a chave pública da empresa, mas também contém informações como o nome de domínio. O cliente envia claramente uma solicitação para www.baidu.com, mas a resposta é na verdade www.qq.com, o que torna você muito desconfortável. Razoavelmente, o armazenamento do certificado impede que o intermediário modifique os dados enviados pelo servidor ao cliente e, uma vez modificado, será detectado

A agência CA usa a chave privada para gerar assinaturas de dados, o que evita com sucesso que o intermediário modifique os dados de informações do servidor e represente o servidor para se comunicar com o cliente. No entanto, o intermediário também conhece a chave pública da organização CA e também conhece a chave pública do servidor. A chave simétrica X dados para descriptografar. Portanto, ele ainda conhece o conteúdo de nossa comunicação na web, mas não pode modificá-lo

Acho que você gosta

Origin blog.csdn.net/m0_69442905/article/details/128748624
Recomendado
Clasificación