Spring Authorization Server1.0 介绍与使用

article/2025/10/12 6:51:34

一、版本使用

   1、Java:17或者更高的版本。

   2、springboot 3.0

   3、Spring Authorization Server 1.0版本。

<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-oauth2-authorization-server</artifactId><version>1.0.0</version>
</dependency>

二、OAuth2涉及的参与者

  • RO (resource owner): 资源所有者,对资源具有授权能力的人。也就是登录用户。
  • RS (resource server): 资源服务器,它存储资源,并处理对资源的访问请求。
  • Client: 第三方应用,它获得RO的授权后便可以去访问RO的资源。
  • AS (authorization server): 授权服务器,它认证RO的身份,为RO提供授权审批流程,并最终颁发授权令牌(Access Token)。

注意:为了便于协议的描述,这里只是在逻辑上把AS与RS区分开来;在物理上,AS与RS的功能可以由同一个服务器来提供服务。

三、授权服务器(authorization server)

   授权服务器授权的类型有三种:授权码模式、客户端模式、刷新模式。

1、授权码模式(authorization_code) 

 步骤:

(A)用户访问客户端,后者将前者导向认证服务器。(B)用户选择是否给予客户端授权。(C)假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。(D)客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。

参数说明:

A步骤中,客户端申请认证的URI,包含以下参数:

  • response_type:表示授权类型,必选项,此处的值固定为"code"
  • client_id:表示客户端的ID,必选项
  • redirect_uri:表示重定向URI,可选项
  • scope:表示申请的权限范围,可选项
  • state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。

示例:

http://localhost:9000/oauth2/authorize?response_type=code&client_id=messaging-client&scope=message.read&redirect_uri=http://127.0.0.1:8080/authorized

通过示例请求出现一个登录界面:

输入你配置的账号及密码,若是账号密码没有问题,则会返回授权码既是路径中出现code="ssssssss"。若是出现输入账号密码都没有问题,却返回账号密码相关的问题(No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken) 

此时需要查看你密码加密问题,后面配置编码器的时候会提一下。

若是路径没有返回code,则去数据库(oauth2_authorization)看看有木有出现授权码(authorization_code_value),若有直接复制。

接着根据授权码获取token,如:

 此处需要注意:需要增加客户端的配置信息(clientId、clientSecret)

 最后获取:

2、客户端模式(client_credentials)

 客户端模式指客户端以自己的名义,而不是以用户的名义,向服务提供商进行认证。

 接着输入客户端配置信息:

最后得到:

注意:客户端模式无刷新token操作。

 3、刷新模式(refresh_token)

涉及参数:配置客户端信息、grant_type、refresh_token.

接着添加客户端配置信息:

最后得到:

 4、授权服务器配置

AuthorizationServerConfig配置:
package com.allen.demoserver.config;import com.allen.component.redis.repository.RedisRepository;
import com.allen.demoserver.service.RedisToJdbcService;
import com.allen.demoserver.service.impl.RedisOAuth2AuthorizationConsentService;
import com.allen.demoserver.service.impl.RedisOAuth2AuthorizationService;
import com.allen.demoserver.service.impl.RedisToJdbcServiceImpl;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.oidc.OidcScopes;
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationConsentService;
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
import org.springframework.security.oauth2.server.authorization.settings.TokenSettings;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.time.Duration;
import java.util.UUID;@Configuration(proxyBeanMethods = false)
public class AuthorizationServerConfig {@Bean@Order(Ordered.HIGHEST_PRECEDENCE)public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)throws Exception {OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);http.getConfigurer(OAuth2AuthorizationServerConfigurer.class).oidc(Customizer.withDefaults());	// Enable OpenID Connect 1.0http// Redirect to the login page when not authenticated from the// authorization endpoint.exceptionHandling((exceptions) -> exceptions.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login")))// Accept access tokens for User Info and/or Client Registration.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);return http.build();}/*** oauth2 用于第三方认证,RegisteredClientRepository 主要用于管理第三方(每个第三方就是一个客户端)** @return*/@Beanpublic RegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTemplate) {RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString()).clientId("demo-client").clientSecret("{noop}secret").clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC).authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE).authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN).authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS).redirectUri("http://127.0.0.1:8080/login/oauth2/code/demo-client-oidc").redirectUri("http://127.0.0.1:8080/authorized").scope(OidcScopes.OPENID).scope(OidcScopes.PROFILE).scope("message.read").scope("message.write").clientSettings(ClientSettings.builder()//client端请求 jwt解密算法.jwkSetUrl("http://localhost:9090/oauth2/jwks").requireAuthorizationConsent(true).build()).tokenSettings(TokenSettings.builder()//使用透明方式,默认是 OAuth2TokenFormat SELF_CONTAINED,生成 JWT 加密方式// SELF_CONTAINED 生成 JWT 加密方式
//				.idTokenSignatureAlgorithm(SignatureAlgorithm.RS256)
//				.accessTokenFormat(OAuth2TokenFormat.SELF_CONTAINED).authorizationCodeTimeToLive(Duration.ofHours(1)).accessTokenTimeToLive(Duration.ofHours(2)).refreshTokenTimeToLive(Duration.ofHours(3)).reuseRefreshTokens(false).build()).build();// Save registered client in db as if in-memoryJdbcRegisteredClientRepository registeredClientRepository = new JdbcRegisteredClientRepository(jdbcTemplate);if (null == registeredClientRepository.findByClientId("demo-client")){registeredClientRepository.save(registeredClient);}return registeredClientRepository;}
//    @Bean
//    public RedisToJdbcService redisToJdbcService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) {
//        return new RedisToJdbcServiceImpl(jdbcTemplate, registeredClientRepository);
//    }
//    @Bean
//    public OAuth2AuthorizationService authorizationService(RegisteredClientRepository registeredClientRepository,RedisRepository redisRepository
//            ,RedisToJdbcService redisToJdbcService) {
//        return new RedisOAuth2AuthorizationService(registeredClientRepository,redisRepository,redisToJdbcService);
//    }@Beanpublic OAuth2AuthorizationService authorizationService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) {return new JdbcOAuth2AuthorizationService(jdbcTemplate, registeredClientRepository);}@Beanpublic OAuth2AuthorizationConsentService authorizationConsentService(JdbcTemplate jdbcTemplate, RegisteredClientRepository registeredClientRepository) {return new JdbcOAuth2AuthorizationConsentService(jdbcTemplate, registeredClientRepository);}
//    @Bean
//    public OAuth2AuthorizationConsentService authorizationConsentService(RedisRepository redisRepository, RedisToJdbcService redisToJdbcService) {
//        return new RedisOAuth2AuthorizationConsentService(redisRepository,redisToJdbcService);
//    }/*** 用于给access_token签名使用。** @return*/@Beanpublic JWKSource<SecurityContext> jwkSource() {KeyPair keyPair = generateRsaKey();RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();RSAKey rsaKey = new RSAKey.Builder(publicKey).privateKey(privateKey).keyID(UUID.randomUUID().toString()).build();JWKSet jwkSet = new JWKSet(rsaKey);return new ImmutableJWKSet<>(jwkSet);}private static KeyPair generateRsaKey() {KeyPair keyPair;try {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(2048);keyPair = keyPairGenerator.generateKeyPair();}catch (Exception ex) {throw new IllegalStateException(ex);}return keyPair;}@Beanpublic JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);}/*** 配置Authorization Server实例* @return*/@Beanpublic AuthorizationServerSettings authorizationServerSettings() {return AuthorizationServerSettings.builder().build();}}
配置说明:
  • authorizationServerSecurityFilterChain : 关于Protocol Endpoints.(协议端点)配置
  • registeredClientRepository: 关于客户端的一些配置                      
  •  authorizationService: 关于OAuth2Authorization 授权信息的处理    
  •  authorizationConsentService: 关于OAuth2AuthorizationConsent信息的处理(入库)
  •  jwkSource()、generateRsaKey()、jwtDecoder: 关于token生成规则的处理
  • authorizationServerSettings: 关于AuthorizationServerSettings【授权服务器】的配置,含路径及接口。

注意:authorizationService、authorizationConsentService 目前框架提供InMemoryOAuth2AuthorizationService(内存)、JdbcOAuth2AuthorizationService(数据库)。若需要实现Redis存储,需要自己去实现OAuth2AuthorizationService接口。关于redis的实现,可以项目看源码

DefaultSecurityConfig配置:
package com.allen.demoserver.config;import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.oidc.OidcScopes;
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.UUID;/*** @author xuguocai* @date 2022/12/13 21:55**/
@EnableWebSecurity
@Configuration(proxyBeanMethods = false)
public class DefaultSecurityConfig {/*** 这个也是个Spring Security的过滤器链,用于Spring Security的身份认证。* @param http* @return* @throws Exception*/@Bean@Order(2)public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)throws Exception {http.authorizeHttpRequests((authorize) -> authorize.anyRequest().authenticated())// Form login handles the redirect to the login page from the// authorization server filter chain.formLogin(Customizer.withDefaults());return http.build();}/*** 配置用户信息,或者配置用户数据来源,主要用于用户的检索。* @return*/@BeanUserDetailsService users() {UserDetails user = User.withDefaultPasswordEncoder().username("user1").password("123456").roles("USER").build();return new InMemoryUserDetailsManager(user);}public static void main(String[] args) {BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();String encode = bCryptPasswordEncoder.encode("123456");System.out.println(encode);}
}

配置说明:

defaultSecurityFilterChain:关于过滤器链的验证配置。
users():关于UserDetailsService 的实现,此处密码基于源码默认PasswordEncoder处理。

 注意:基于代码学习,可以使用默认的编码器,既是如上配置方式。若是接口的实现,需要注意引入的编码器对密码的加密。若是配置的编码器出现问题,会影响授权码获取code。

package com.allen.demoserver.service;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;/*** @author xuguocai* @date 2022/11/24 17:06**/
@Slf4j
@Service
public class UserDetailsServiceImpl implements UserDetailsService {@Autowiredprivate UserClient userClient;// 需要注入 new BCryptPasswordEncoder(),既是自己定义这个bean@Autowiredprivate PasswordEncoder passwordEncoder;/*** 基于用户名获取数据库中的用户信息* @param username 这个username来自客户端* @return* @throws UsernameNotFoundException*/@Overridepublic UserDetails loadUserByUsername(String username)throws UsernameNotFoundException {log.info("loadUserByUsername   {}",username);//基于feign方式获取远程数据并封装//1.基于用户名获取用户信息UserVO data = userClient.selectUserByUserName(username);if(data==null) {throw new UsernameNotFoundException("用户不存在");}//2.基于用于id查询用户权限String password = passwordEncoder.encode(data.getPassword());
//		log.info("数据:{}",data);//3.对查询结果进行封装并返回return new User(username, password,AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN"));//返回给认证中心,认证中心会基于用户输入的密码以及数据库的密码做一个比对}}

在配置中,需要注入上面的bean:

 此处需要注意编码器的注入,配置不当会影响授权码的账号密码输入,获取不到code值。

 至此,授权服务器配置完毕。需要拓展的根据自己的需求拓展。

四、资源服务器(resource-server)与客户端(oauth2-client)

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-resource-server</artifactId></dependency>

此处不再描述,可以查看oauth2-resource 项目,关注它的配置类、配置文件,其次再关注获取全局用户方式。

获取全局用户:它是根据jwt token获取,传的token经过过滤器链,既是【securityFilterChain(HttpSecurity http)】配置,最后从token中获取用户信息。

文章对应的源码地址:gc-oauth2项目

参考地址:

Spring Authorization Server 官网

Spring Authorization Server 官网示例

OAuth 2.0之授权码模式


http://chatgpt.dhexx.cn/article/GMHUGBEk.shtml

相关文章

curl php authorization,PHP CURL 执行 Authorization 请求

PHP CURL 扩展可以帮助我们快速实现HTTP请求。查看更多: 博客原文 在使用豆瓣OAuth登录接口时&#xff0c;我们需要发送这样的HTTP REQUEST 请求:GET /v2/user/~me HTTP/1.1 Host: https://api.douban.comAuthorization: Bearer a14afef0f66fcffce3e0fcd2e34f6ff4 在命令行中我…

spring authorization server使用说明

spring authorization server使用说明 相关依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- 授权客户端 --><dependency><groupId…

Spring Authorization Server 系列(二)获取授权码

Spring Authorization Server 系列&#xff08;二&#xff09;获取授权码 概述获取授权码获取授权码的url逻辑解析匹配url参数解析 概述 Spring Authorization Server 是基于 OAuth2.1 和 OIDC 1.0 的。 只有 授权码&#xff0c;刷新token&#xff0c;客户端模式。 获取授权码…

Spring Authorization Server 0.2.3变化

目录 引言联邦认证示例public client默认设置Introspection端点自定义访问令牌类型⭐️令牌生成器优化⭐️拆分Client认证逻辑OAuth2ClientAuthenticationProvider⭐️授权端点逻辑⭐️关于0.3.0版本中JwtEncoder相关变化⭐️ 引言 Spring社区在2022-03-24 19:56发布了Spring …

spring authorization server 0.3.1 - 默认示例

spring authorization server 0.3.1 - 默认oidc 开始1、default-authorizationserver项目1.1、AuthorizationServerConfig.java1.2、DefaultSecurityConfig.java1.3、Jwks.java1.4、KeyGeneratorUtils.java1.5、DefaultAuthorizationServer.java1.6、application.yml 2、client…

Authorization Server 认证服务

Hi Auth HiAuth是一个开源的基于Oauth2协议的认证、授权系统&#xff0c;除了标准的Oauth2授权流程功能外&#xff0c;还提供了应用管理、用户管理、权限管理等相关功能。 在这个项目中你能够了解到如何基于spring-security-oauth2-authorization-server实现自己的Authorizat…

java authorization_OkHttp3 之 Authorization处理认证(四)

处理验证 这部分和HTTP AUTH有关. HTTP AUTH 使用HTTP AUTH需要在server端配置http auth信息, 其过程如下:客户端发送http请求 服务器发现配置了http auth, 于是检查request里面有没有”Authorization”的http header 如果有, 则判断Authorization里面的内容是否在用户列表里面…

shiro授权过程

一、授权的核心概念 授权&#xff0c;也就是权限认证或访问控制&#xff0c;即在应用中控制谁能访问哪些资源 授权中的核心要素&#xff1a; 1 用户&#xff0c;在shiro中代表访问系统的任何客户端&#xff0c;即subject 2 角色&#xff0c;是权限的集合&#xff0c;或字符串值…

安全-认证授权、数据脱敏

一、认证授权 JWT &#xff1a;JWT&#xff08;JSON Web Token&#xff09;是一种身份认证的方式&#xff0c;JWT 本质上就一段签名的 JSON 格式的数据。由于它是带有签名的&#xff0c;因此接收者便可以验证它的真实性。 SSO(单点登录) &#xff1a;SSO(Single Sign On) 即单…

认证 (authentication) 和授权 (authorization) 的区别

以前一直傻傻分不清各种网际应用中 authentication 和 authorization, 其实很简单: 这两个术语通常在安全性方面相互结合使用&#xff0c;尤其是在获得对系统的访问权限时。两者都是非常重要的主题&#xff0c;通常与网络相关联&#xff0c;作为其服务基础架构的关键部分。然而…

Authorization—权限控制流程

本篇是对Shiro体系架构的介绍&#xff0c;本栏目大部分内容来自于Shiro官网。翻译过程中已经尽量保证用词的准确性和易懂性&#xff0c;如有不准确或者不确切的地方&#xff0c;请联系作者加以修改。本篇内容翻译自Authorization特征与Authorization官方指南。 Authorization&…

认证 (Authentication) 和授权 (Authorization)的区别是什么?

说简单点就是&#xff1a; 认证 (Authentication)&#xff1a; 你是谁。 授权 (Authorization)&#xff1a; 你有哪些权限 干什么事情。 稍微正式点&#xff08;啰嗦点&#xff09;的说法就是&#xff1a; Authentication&#xff08;认证&#xff09; 是验证您的身份的凭据&a…

变量定义与类型

命名 保留字与关键字 关键字是系统已经用的&#xff0c;保留字是系统自带的的保留 为以后使用做准备 查看关键字方法 import keyword #引入关键字模块 print &#xff08;keyword.kwlist&#xff09; #打印系统全部关键字 变量声明 三种格 #格式1 s1 &#xff02;北京图灵学…

Java变量定义时候的注意事项

常量定义的基本注意事项 在JAVA语言中&#xff0c;主要利用final关键字&#xff0c;&#xff08;在java类中灵活使用Static关键字&#xff09;来定义常量。 当常量被设定后&#xff0c;一般情况下就不允许在进行修改&#xff0c;如可以利用以下形式来定义一个常量:final doubl…

变量的定义和使用

目录 一、变量的定义 二、变量的组成 1.标识 2.类型 3.值 三、变量的多次赋值 一、变量的定义 变量名(name) 赋值运算符() 值(小王) name 小王 二、变量的组成 1.标识 表示对象所存储的物理地址&#xff0c;使用内置函数 id(obj) 来获取。 print(id(name)) 运行…

C语言中变量声明和变量定义的区别

本文转载至CSDN博客JeanCheng 变量声明和变量定义 变量定义&#xff1a;用于为变量分配存储空间&#xff0c;还可为变量指定初始值。程序中&#xff0c;变量有且仅有一个定义。变量声明&#xff1a;用于向程序表明变量的类型和名字。定义也是声明&#xff0c;extern声明不是定义…

C++ 中的变量定义

变量定义就是告诉编译器在何处创建变量的存储&#xff0c;以及如何创建变量的存储。 变量定义指定一个数据类型&#xff0c;并包含了该类型的一个或多个变量的列表&#xff0c;如下所示&#xff1a; type variable_list; 在这里&#xff0c;type 必须是一个有效的 C 数据类型…

十:变量的定义和声明的区别?

1. 变量的声明&#xff1a; 声明是用来告诉编译器变量的名称和类型&#xff0c;而不分配内存。变量的声明有两重含义&#xff1a; 告诉编译器&#xff0c;这个名字已经匹配到一块内存上&#xff0c;下面的代码用到变量或者对象是在别的地方定义的。声明可以出现多次。 告诉编译…

C语言基础教程 之 如何定义变量!

变量定义就是告诉编译器在何处创建变量的存储&#xff0c;以及如何创建变量的存储。变量定义指定一个数据类型&#xff0c;并包含了该类型的一个或多个变量的列表&#xff0c;如下所示&#xff1a; type variable_list; 在这里&#xff0c;type 必须是一个有效的 C 数据类型&…

变量的定义

变量 变量用于存储编程所使用的数据和方法。 声明一般变量的关键字&#xff1a;var,let,const.其中let和const是es6的语法。 声明其他特殊变量的关键字&#xff1a;function,class,improt&#xff08;先了解&#xff09;等 声明变量 变量用于存储数据,因此可以把变量实际上就…