【OAuth2】:赋予用户控制权的安全通行证--代码模拟篇

2023-12-27 02:28

本文主要是介绍【OAuth2】:赋予用户控制权的安全通行证--代码模拟篇,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

🥳🥳Welcome Huihui's Code World ! !🥳🥳

接下来看看由辉辉所写的关于OAuth2的相关操作吧 

 上篇已经讲了oauth2的相关知识,详解了oauth2的四种授权模式中的授权码模式,那么这一篇我们就来讲一下授权码模式的代码实现,但是为了更好的讲解其中的相关知识点,这里用的是模拟代码【没有连接数据库进行验证】

目录

🥳🥳Welcome Huihui's Code World ! !🥳🥳

一.代码准备

1.client

1.1pom

1.2controller

2.resource-owner

2.1pom

2.2controller

3.authorization-server

3.1pom

3.2controller

4.resource-server

4.1pom

4.2controller

5.整体项目的pom依赖

二.授权码模式的模拟代码流程讲解 

1.用户访问页面

2.访问的页面将请求重定向到认证服务器

​3.认证服务器向用户展示授权页面,等待用户授权

4.用户授权完成

5.获取令牌(Token)


一.代码准备

1.client

1.1pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>client</artifactId><version>0.0.1-SNAPSHOT</version><name>client</name><description>client</description><parent><artifactId>Oauth</artifactId><groupId>org.example</groupId><version>1.0-SNAPSHOT</version></parent><dependencies><dependency><groupId>org.apache.oltu.oauth2</groupId><artifactId>org.apache.oltu.oauth2.client</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.4.1</version><configuration><mainClass>com.example.client.ClientApplication</mainClass></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build></project>

1.2controller

package com.example.client.controller;import lombok.extern.slf4j.Slf4j;
import org.apache.oltu.oauth2.client.HttpClient;
import org.apache.oltu.oauth2.client.OAuthClient;
import org.apache.oltu.oauth2.client.URLConnectionClient;
import org.apache.oltu.oauth2.client.request.OAuthBearerClientRequest;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
import org.apache.oltu.oauth2.client.response.OAuthResourceResponse;
import org.apache.oltu.oauth2.common.OAuth;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.types.GrantType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest;/*** 获取授权的控制器*/
@Controller
@RequestMapping("/client")
@SuppressWarnings("all")
@Slf4j
public class GetAuthorizationController {/*** 客户端: 8080* 资源拥有者: 8081* 认证服务器: 8082* 资源服务器: 8083*/private static String CLIENT_ID = "clientId";private static String CLIENT_SECRET = "clientSecret";private static String CODE_URL = "code";private static String RESPONSE_TYPE = "code";/*认证服务器地址*/private static String AUTH_SERVER_URL = "http://localhost:8082/authServer/token";/*资源拥有者地址*/private static String RESOURCE_OWNER_URL = "http://localhost:8081/owner/";/*资源服务器地址*/private static String RESOURCE_SERVER_URL = "http://localhost:8083/resourceServer/userinfo";/*授权码回调地址*/private static String CALLBACKCODE = "http://localhost:8080/client/callbackCode";/*获取资源地址*/private static String GETRESOURCE = "http://localhost:8080/client/getResource";/*** 客户向资源所有者获取授权码*/@GetMapping("/getCode")public String getCode() throws OAuthSystemException {// 创建OAuthClientRequest对象,设置授权码请求的相关参数OAuthClientRequest oAuthClientRequest = OAuthClientRequest.authorizationLocation(CODE_URL) // 授权码请求的授权服务器地址.setClientId(CLIENT_ID) // 设置客户端ID.setRedirectURI(CALLBACKCODE) // 设置重定向URI.setResponseType(RESPONSE_TYPE) // 设置响应类型为授权码.buildQueryMessage(); // 构建查询消息String uriString = oAuthClientRequest.getLocationUri(); // 获取授权码请求的URI字符串// 重定向到资源所有者,获取验证码return "redirect:" + RESOURCE_OWNER_URL + uriString;}/*** 1. 资源所有者在生成授权码之后,会回调该接口将授权码传回给客户* 2. 客户获取授权码之后,使用该接口向认证服务器申请令牌*/@RequestMapping("/callbackCode")public String callbackCode(HttpServletRequest request) throws OAuthSystemException, OAuthProblemException {// 从请求中获取授权码String code = request.getParameter("code");log.info(" --- 从资源拥有者获取code: {} -----------", code);// 创建OAuthClient对象,用于与认证服务器进行通信OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());// 创建OAuthClientRequest对象,设置令牌请求的相关参数OAuthClientRequest tokenRequest = OAuthClientRequest.tokenLocation(AUTH_SERVER_URL) // 令牌请求的认证服务器地址.setClientId(CLIENT_ID) // 设置客户端ID.setClientSecret(CLIENT_SECRET) // 设置客户端密钥.setGrantType(GrantType.AUTHORIZATION_CODE) // 设置授权类型为授权码.setCode(code) // 设置授权码.setRedirectURI(CALLBACKCODE) // 设置重定向URI.buildQueryMessage(); // 构建查询消息// 通过Code,向认证服务器申请令牌OAuthJSONAccessTokenResponse tokenResp = oAuthClient.accessToken(tokenRequest, OAuth.HttpMethod.POST); // 发送请求并获取响应// 从响应中获取访问令牌String accessToken = tokenResp.getAccessToken();log.info("客户获取的访问令牌:" + accessToken);return "redirect:" + GETRESOURCE + "?accessToken=" + accessToken;}/*** 使用令牌获取资源服务器中的数据*/@GetMapping("/getResource")@ResponseBodypublic String getResource(String accessToken) throws OAuthSystemException, OAuthProblemException {log.info("客户使用令牌向资源服务器获取数据 token = " + accessToken);// 创建OAuthClient对象,用于与资源服务器进行通信OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());// 创建OAuthClientRequest对象,设置用户信息请求的相关参数OAuthClientRequest userInfoRequest =new OAuthBearerClientRequest(RESOURCE_SERVER_URL) // 用户信息请求的资源服务器地址.setAccessToken(accessToken) // 设置访问令牌.buildHeaderMessage(); // 构建请求头消息// 向资源服务器发送请求并获取响应OAuthResourceResponse resourceResponse = oAuthClient.resource(userInfoRequest, OAuth.HttpMethod.GET, OAuthResourceResponse.class);// 从响应中获取用户信息String userInfo = resourceResponse.getBody();log.info("客户获取的资源服务器的数据: " + userInfo);return userInfo;}}

2.resource-owner

2.1pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>resource-owner</artifactId><version>0.0.1-SNAPSHOT</version><name>resource-owner</name><description>resource-owner</description><parent><artifactId>Oauth</artifactId><groupId>org.example</groupId><version>1.0-SNAPSHOT</version></parent><dependencies><dependency><groupId>org.apache.oltu.oauth2</groupId><artifactId>org.apache.oltu.oauth2.authzserver</artifactId></dependency><dependency><groupId>org.apache.oltu.oauth2</groupId><artifactId>org.apache.oltu.oauth2.resourceserver</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.4.1</version><configuration><mainClass>com.example.owner.ResourceOwnerApplication</mainClass></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build></project>

2.2controller

package com.example.owner.controller;import lombok.extern.slf4j.Slf4j;
import org.apache.oltu.oauth2.as.request.OAuthAuthzRequest;
import org.apache.oltu.oauth2.as.response.OAuthASResponse;
import org.apache.oltu.oauth2.common.OAuth;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.OAuthResponse;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Controller // 声明这是一个控制器类
@RequestMapping("/owner") // 设置请求映射路径为 /owner
@Slf4j // 使用 Lombok 的 @Slf4j 注解,简化日志记录
@SuppressWarnings("all") // 忽略所有警告
public class CodeController {@GetMapping("/code") // 定义一个处理 GET 请求的方法,映射路径为 /codepublic String sendCode(HttpServletRequest request) {log.info("resource owner send code"); // 记录日志信息try {OAuthAuthzRequest oathReq = new OAuthAuthzRequest(request); // 从请求中获取 OAuthAuthzRequest 对象if (StringUtils.hasLength(oathReq.getClientId())) { // 如果客户端ID存在//设置授权码String code = "authorizationCode";String responseType = oathReq.getResponseType();//获取构建响应的对象OAuthASResponse.OAuthAuthorizationResponseBuilder builder =OAuthASResponse.authorizationResponse(request, HttpServletResponse.SC_OK);builder.setCode(code); // 设置授权码String redirectURI = oathReq.getParam(OAuth.OAUTH_REDIRECT_URI); // 获取重定向URIOAuthResponse oauthResp = builder.location(redirectURI).buildQueryMessage(); // 构建查询消息log.info("resource owner send code "); // 记录日志信息String uri = oauthResp.getLocationUri(); // 获取重定向URIreturn "redirect:" + uri; // 返回重定向URL}} catch (OAuthSystemException e) { // 捕获 OAuthSystemException 异常e.printStackTrace(); // 打印异常堆栈信息} catch (OAuthProblemException e) { // 捕获 OAuthProblemException 异常e.printStackTrace(); // 打印异常堆栈信息}return null; // 如果发生异常或客户端ID不存在,返回 null}}

3.authorization-server

3.1pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>authorization-server</artifactId><version>0.0.1-SNAPSHOT</version><name>authorization-server</name><description>authorization-server</description><parent><artifactId>Oauth</artifactId><groupId>org.example</groupId><version>1.0-SNAPSHOT</version></parent><dependencies><dependency><groupId>org.apache.oltu.oauth2</groupId><artifactId>org.apache.oltu.oauth2.authzserver</artifactId></dependency><dependency><groupId>org.apache.oltu.oauth2</groupId><artifactId>org.apache.oltu.oauth2.resourceserver</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.4.1</version><configuration><mainClass>com.example.authorization.AuthorizationServerApplication</mainClass></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build></project>

3.2controller
 

package com.example.authorization.controller;import lombok.extern.slf4j.Slf4j;
import org.apache.oltu.oauth2.as.issuer.MD5Generator;
import org.apache.oltu.oauth2.as.issuer.OAuthIssuerImpl;
import org.apache.oltu.oauth2.as.request.OAuthTokenRequest;
import org.apache.oltu.oauth2.as.response.OAuthASResponse;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.OAuthResponse;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Controller // 声明这是一个控制器类
@RequestMapping("/authServer") // 设置请求映射路径为 /authServer
@Slf4j // 使用 Lombok 的 @Slf4j 注解,简化日志记录
@SuppressWarnings("all") // 忽略所有警告
public class AuthController {@PostMapping("/token") // 定义一个处理 POST 请求的方法,映射路径为 /tokenpublic HttpEntity getAccessToken(HttpServletRequest request) throws OAuthProblemException, OAuthSystemException {log.info("认证服务器,接收到客户的令牌请求 .... "); // 记录日志信息OAuthTokenRequest tokenReq = new OAuthTokenRequest(request); // 从请求中获取 OAuthTokenRequest 对象String clientSecret = tokenReq.getClientSecret(); // 获取客户端密钥if (StringUtils.hasLength(clientSecret)) { // 如果客户端密钥存在OAuthIssuerImpl oAuthIssuer = new OAuthIssuerImpl(new MD5Generator()); // 创建一个 OAuthIssuerImpl 对象,使用 MD5Generator 生成签名算法String token = oAuthIssuer.accessToken(); // 生成访问令牌log.info("token = " + token); // 记录日志信息//构造保护令牌的响应对象OAuthResponse oAuthResponse = OAuthASResponse.tokenResponse(HttpServletResponse.SC_OK) // 设置响应状态码为 200 OK.setAccessToken(token) // 设置访问令牌.buildJSONMessage(); // 构建 JSON 格式的响应消息return new ResponseEntity(oAuthResponse.getBody(), HttpStatus.valueOf(oAuthResponse.getResponseStatus())); // 返回响应实体}return null; // 如果客户端密钥不存在,返回 null}}

4.resource-server

4.1pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>resource-server</artifactId><version>0.0.1-SNAPSHOT</version><name>resource-server</name><description>resource-server</description><parent><artifactId>Oauth</artifactId><groupId>org.example</groupId><version>1.0-SNAPSHOT</version></parent><dependencies><dependency><groupId>org.apache.oltu.oauth2</groupId><artifactId>org.apache.oltu.oauth2.authzserver</artifactId></dependency><dependency><groupId>org.apache.oltu.oauth2</groupId><artifactId>org.apache.oltu.oauth2.resourceserver</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.4.1</version><configuration><mainClass>com.example.resource.ResourceServerApplication</mainClass></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build></project>

4.2controller

package com.example.resource.controller;import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.types.ParameterStyle;
import org.apache.oltu.oauth2.rs.request.OAuthAccessResourceRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;@RestController // 声明这是一个控制器类
@RequestMapping("/resourceServer") // 设置请求映射路径为 /resourceServer
@SuppressWarnings("all") // 忽略所有警告
public class UserController {@GetMapping("/userinfo") // 定义一个处理 GET 请求的方法,映射路径为 /userinfopublic Object getUserInfo(HttpServletRequest request) throws OAuthProblemException, OAuthSystemException {// 创建一个 OAuthAccessResourceRequest 对象,用于处理 OAuth 认证请求OAuthAccessResourceRequest oAuthAccessResourceRequest = new OAuthAccessResourceRequest(request, ParameterStyle.HEADER);// 获取访问令牌String accessToken = oAuthAccessResourceRequest.getAccessToken();// 创建一个 Map 对象,用于存储用户信息Map<String, Object> map = new HashMap<>();// 向 Map 中添加用户信息map.put("name", "zhengsuanfeng");map.put("phone", "13576472774");map.put("addr", "长沙岳麓区");// 返回用户信息return map;}}

5.整体项目的pom依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://maven.apache.org/POM/4.0.0"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>Oauth</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><modules><module>client</module><module>resource-owner</module><module>authorization-server</module><module>resource-server</module></modules><properties><oauth2.version>0.31</oauth2.version><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.4.1</spring-boot.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.apache.oltu.oauth2</groupId><artifactId>org.apache.oltu.oauth2.client</artifactId><version>${oauth2.version}</version></dependency><dependency><groupId>org.apache.oltu.oauth2</groupId><artifactId>org.apache.oltu.oauth2.authzserver</artifactId><version>${oauth2.version}</version></dependency><dependency><groupId>org.apache.oltu.oauth2</groupId><artifactId>org.apache.oltu.oauth2.resourceserver</artifactId><version>${oauth2.version}</version></dependency></dependencies></dependencyManagement></project>

二.授权码模式的模拟代码流程讲解 

1.用户访问页面


2.访问的页面将请求重定向到认证服务器


3.认证服务器向用户展示授权页面,等待用户授权


4.用户授权完成

认证服务器带上client_id发送给应用服务器资源服务器➡生成一个code

然后,用户拿到code

5.获取令牌(Token)

将code、client_id、client_secret传给认证服务器换取access_token


 

6.将access_token传给资源服务器


7.验证token,访问真正的资源页面

拿到数据

好啦,今天的分享就到这了,希望能够帮到你呢!😊😊    

这篇关于【OAuth2】:赋予用户控制权的安全通行证--代码模拟篇的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/541590

相关文章

Security OAuth2 单点登录流程

单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自独立的软件系统,提供访问控制的属性。当拥有这项属性时,当用户登录时,就可以获取所有系统的访问权限,不用对每个单一系统都逐一登录。这项功能通常是以轻型目录访问协议(LDAP)来实现,在服务器上会将用户信息存储到LDAP数据库中。相同的,单一注销(single sign-off)就是指

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

usaco 1.2 Transformations(模拟)

我的做法就是一个一个情况枚举出来 注意计算公式: ( 变换后的矩阵记为C) 顺时针旋转90°:C[i] [j]=A[n-j-1] [i] (旋转180°和270° 可以多转几个九十度来推) 对称:C[i] [n-j-1]=A[i] [j] 代码有点长 。。。 /*ID: who jayLANG: C++TASK: transform*/#include<

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

客户案例:安全海外中继助力知名家电企业化解海外通邮困境

1、客户背景 广东格兰仕集团有限公司(以下简称“格兰仕”),成立于1978年,是中国家电行业的领军企业之一。作为全球最大的微波炉生产基地,格兰仕拥有多项国际领先的家电制造技术,连续多年位列中国家电出口前列。格兰仕不仅注重业务的全球拓展,更重视业务流程的高效与顺畅,以确保在国际舞台上的竞争力。 2、需求痛点 随着格兰仕全球化战略的深入实施,其海外业务快速增长,电子邮件成为了关键的沟通工具。

安全管理体系化的智慧油站开源了。

AI视频监控平台简介 AI视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。用户只需在界面上进行简单的操作,就可以实现全视频的接入及布控。摄像头管理模块用于多种终端设备、智能设备的接入及管理。平台支持包括摄像头等终端感知设备接入,为整个平台提

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

2024网安周今日开幕,亚信安全亮相30城

2024年国家网络安全宣传周今天在广州拉开帷幕。今年网安周继续以“网络安全为人民,网络安全靠人民”为主题。2024年国家网络安全宣传周涵盖了1场开幕式、1场高峰论坛、5个重要活动、15场分论坛/座谈会/闭门会、6个主题日活动和网络安全“六进”活动。亚信安全出席2024年国家网络安全宣传周开幕式和主论坛,并将通过线下宣讲、创意科普、成果展示等多种形式,让广大民众看得懂、记得住安全知识,同时还

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d