492 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			492 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C#
		
	
	
| using Amazon.Auth.AccessControlPolicy;
 | ||
| using Amazon.SecurityToken;
 | ||
| using AutoMapper;
 | ||
| using Azure.Core;
 | ||
| using IdentityModel.Client;
 | ||
| using IdentityModel.OidcClient;
 | ||
| using IRaCIS.Application.Contracts;
 | ||
| using IRaCIS.Application.Interfaces;
 | ||
| using IRaCIS.Core.Application.Auth;
 | ||
| using IRaCIS.Core.Application.Contracts;
 | ||
| using IRaCIS.Core.Application.Helper;
 | ||
| using IRaCIS.Core.Application.Service;
 | ||
| using IRaCIS.Core.Domain.Models;
 | ||
| using IRaCIS.Core.Domain.Share;
 | ||
| using IRaCIS.Core.Infra.EFCore;
 | ||
| using IRaCIS.Core.Infrastructure.Extention;
 | ||
| using MassTransit;
 | ||
| using MassTransit.Futures.Contracts;
 | ||
| using Microsoft.AspNetCore.Authorization;
 | ||
| using Microsoft.AspNetCore.Http;
 | ||
| using Microsoft.AspNetCore.Mvc;
 | ||
| using Microsoft.Extensions.Logging;
 | ||
| using Microsoft.Extensions.Options;
 | ||
| using RestSharp;
 | ||
| using RestSharp.Authenticators;
 | ||
| using System;
 | ||
| using System.Collections.Generic;
 | ||
| using System.Linq;
 | ||
| using System.Net;
 | ||
| using System.Net.Http;
 | ||
| using System.Text;
 | ||
| using System.Text.Json;
 | ||
| using System.Threading.Tasks;
 | ||
| using ZiggyCreatures.Caching.Fusion;
 | ||
| using AssumeRoleRequest = Amazon.SecurityToken.Model.AssumeRoleRequest;
 | ||
| using LoginReturnDTO = IRaCIS.Application.Contracts.LoginReturnDTO;
 | ||
| 
 | ||
| namespace IRaCIS.Api.Controllers
 | ||
| {
 | ||
|     /// <summary>
 | ||
|     /// 医生基本信息 、工作信息  专业信息、审核状态
 | ||
|     /// </summary>
 | ||
|     [ApiController, ApiExplorerSettings(GroupName = "Reviewer")]
 | ||
|     public class ExtraController([FromServices] IAttachmentService attachmentService, [FromServices] IDoctorService _doctorService,
 | ||
|             [FromServices] IEducationService _educationService, [FromServices] ITrialExperienceService _trialExperienceService,
 | ||
| 
 | ||
|             [FromServices] IResearchPublicationService _researchPublicationService, [FromServices] IVacationService _vacationService) : ControllerBase
 | ||
|     {
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         ///  获取医生详情 
 | ||
|         /// </summary>
 | ||
|         /// <param name="attachmentService"></param>
 | ||
|         /// <param name="_doctorService"></param>
 | ||
|         /// <param name="_educationService"></param>
 | ||
|         /// <param name="_trialExperienceService"></param>
 | ||
|         /// <param name="_researchPublicationService"></param>
 | ||
|         /// <param name="_vacationService"></param>
 | ||
|         /// <param name="doctorId"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost, Route("doctor/getDetail")]
 | ||
| 
 | ||
|         public async Task<IResponseOutput<DoctorDetailDTO>> GetDoctorDetail(GetDoctorDetailInDto inDto)
 | ||
|         {
 | ||
|             var education = await _educationService.GetEducation(inDto.doctorId);
 | ||
| 
 | ||
|             var sowList = _doctorService.GetDoctorSowList(inDto.doctorId);
 | ||
|             var ackSowList = _doctorService.GetDoctorAckSowList(inDto.doctorId);
 | ||
| 
 | ||
|             var doctorDetail = new DoctorDetailDTO
 | ||
|             {
 | ||
|                 AuditView = await _doctorService.GetAuditState(inDto.doctorId),
 | ||
|                 BasicInfoView = await _doctorService.GetBasicInfo(inDto.doctorId),
 | ||
|                 EmploymentView = await _doctorService.GetEmploymentInfo(inDto.doctorId),
 | ||
|                 AttachmentList = await attachmentService.GetAttachments(inDto.doctorId),
 | ||
|                 SummarizeInfo = await _doctorService.GetSummarizeInfo(new GetSummarizeInfoInDto()
 | ||
|                 {
 | ||
|                     DoctorId = inDto.doctorId,
 | ||
|                     TrialId = inDto.TrialId
 | ||
|                 }),
 | ||
|                 PaymentModeInfo = await _doctorService.GetPaymentMode(inDto.doctorId),
 | ||
|                 EducationList = education.EducationList,
 | ||
|                 PostgraduateList = education.PostgraduateList,
 | ||
| 
 | ||
|                 TrialExperienceView = await _trialExperienceService.GetTrialExperience(new TrialExperienceModelIndto()
 | ||
|                 {
 | ||
|                     DoctorId = inDto.doctorId,
 | ||
|                     TrialId = inDto.TrialId
 | ||
|                 }),
 | ||
|                 ResearchPublicationView = await _researchPublicationService.GetResearchPublication(inDto.doctorId),
 | ||
| 
 | ||
|                 SpecialtyView = await _doctorService.GetSpecialtyInfo(inDto.doctorId),
 | ||
|                 InHoliday = (await _vacationService.OnVacation(inDto.doctorId)).IsSuccess,
 | ||
|                 IntoGroupInfo = _doctorService.GetDoctorIntoGroupInfo(inDto.doctorId),
 | ||
|                 SowList = sowList,
 | ||
|                 AckSowList = ackSowList
 | ||
|             };
 | ||
| 
 | ||
|             return ResponseOutput.Ok(doctorDetail);
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>  系统用户登录接口[New] </summary>
 | ||
|         [HttpPost, Route("user/login")]
 | ||
|         [AllowAnonymous]
 | ||
|         public async Task<IResponseOutput> Login(UserLoginDTO loginUser,
 | ||
|             [FromServices] IFusionCache _fusionCache,
 | ||
|             [FromServices] IUserService _userService,
 | ||
|             [FromServices] ITokenService _tokenService,
 | ||
|             [FromServices] IReadingImageTaskService readingImageTaskService,
 | ||
|             [FromServices] IOptionsMonitor<ServiceVerifyConfigOption> _verifyConfig,
 | ||
|             [FromServices] IOptionsMonitor<SystemEmailSendConfig> _emailConfig,
 | ||
|             [FromServices] IMapper _mapper,
 | ||
|             [FromServices] IMailVerificationService _mailVerificationService)
 | ||
|         {
 | ||
|             var emailConfig = _emailConfig.CurrentValue;
 | ||
|             var companyInfo = new SystemEmailSendConfigView() { CompanyName = emailConfig.CompanyName, CompanyNameCN = emailConfig.CompanyNameCN, CompanyShortName = emailConfig.CompanyShortName, CompanyShortNameCN = emailConfig.CompanyShortNameCN };
 | ||
| 
 | ||
|             //MFA 邮箱验证  前端传递用户Id  和MFACode
 | ||
|             if (loginUser.UserId != null && _verifyConfig.CurrentValue.OpenLoginMFA)
 | ||
|             {
 | ||
|                 Guid userId = (Guid)loginUser.UserId;
 | ||
| 
 | ||
|                 //验证MFA 编码是否有问题 ,前端要拆开,自己调用验证的逻辑
 | ||
|                 //await _userService.VerifyMFACodeAsync(userId, loginUser.MFACode);
 | ||
| 
 | ||
|                 //var loginUser = await _userRoleRepository.Where(u => u.UserName.Equals(userName) && u.Password == password).ProjectTo<UserBasicInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
 | ||
| 
 | ||
|                 var basicInfo = await _userService.GetUserBasicInfo(userId, loginUser.Password);
 | ||
| 
 | ||
|                 var loginReturn = new LoginReturnDTO() { BasicInfo = basicInfo };
 | ||
| 
 | ||
|                 loginReturn.JWTStr = _tokenService.GetToken(new UserTokenInfo() { IdentityUserId = basicInfo.IdentityUserId });
 | ||
| 
 | ||
| 
 | ||
|                 // 创建一个 CookieOptions 对象,用于设置 Cookie 的属性
 | ||
|                 var option = new CookieOptions
 | ||
|                 {
 | ||
|                     Expires = DateTime.Now.AddMonths(1), // 设置过期时间为 30 分钟之后
 | ||
|                     HttpOnly = false, // 确保 cookie 只能通过 HTTP 访问
 | ||
|                     SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None, // 设置 SameSite 属性
 | ||
|                     Secure = false // 确保 cookie 只能通过 HTTPS 访问
 | ||
|                 };
 | ||
| 
 | ||
|                 HttpContext.Response.Cookies.Append("access_token", loginReturn.JWTStr, option);
 | ||
| 
 | ||
|                 // 验证阅片休息时间
 | ||
|                 await readingImageTaskService.ResetReadingRestTime(userId);
 | ||
| 
 | ||
|                 await _fusionCache.SetAsync(CacheKeys.UserToken(userId), loginReturn.JWTStr, TimeSpan.FromDays(7));
 | ||
| 
 | ||
|                 await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(userId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes));
 | ||
| 
 | ||
|                 loginReturn.CompanyInfo = companyInfo;
 | ||
|                 return ResponseOutput.Ok(loginReturn);
 | ||
| 
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 var returnModel = await _userService.Login(loginUser.UserName, loginUser.Password);
 | ||
| 
 | ||
|                 if (returnModel.IsSuccess)
 | ||
|                 {
 | ||
|                     #region GRPC 调用鉴权中心,因为服务器IIS问题 http/2   故而没法使用
 | ||
| 
 | ||
|                     ////重试策略
 | ||
|                     //var defaultMethodConfig = new MethodConfig
 | ||
|                     //{
 | ||
|                     //    Names = { MethodName.Default },
 | ||
|                     //    RetryPolicy = new RetryPolicy
 | ||
|                     //    {
 | ||
|                     //        MaxAttempts = 3,
 | ||
|                     //        InitialBackoff = TimeSpan.FromSeconds(1),
 | ||
|                     //        MaxBackoff = TimeSpan.FromSeconds(5),
 | ||
|                     //        BackoffMultiplier = 1.5,
 | ||
|                     //        RetryableStatusCodes = { Grpc.Core.StatusCode.Unavailable }
 | ||
|                     //    }
 | ||
|                     //};
 | ||
| 
 | ||
|                     //#region  unable to trust the certificate then the gRPC client can be configured to ignore the invalid certificate
 | ||
| 
 | ||
|                     //var httpHandler = new HttpClientHandler();
 | ||
|                     //// Return `true` to allow certificates that are untrusted/invalid
 | ||
|                     //httpHandler.ServerCertificateCustomValidationCallback =
 | ||
|                     //    HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
 | ||
| 
 | ||
| 
 | ||
|                     //////这一句是让grpc支持本地 http  如果本地访问部署在服务器上,那么是访问不成功的 
 | ||
|                     //AppContext.SetSwitch(
 | ||
|                     //    "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
 | ||
| 
 | ||
|                     //#endregion
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|                     //var grpcAdress = configuration.GetValue<string>("GrpcAddress");
 | ||
|                     ////var grpcAdress = "http://localhost:7200";
 | ||
| 
 | ||
|                     //var channel = GrpcChannel.ForAddress(grpcAdress, new GrpcChannelOptions
 | ||
|                     //{
 | ||
|                     //    HttpHandler = httpHandler,
 | ||
|                     //    ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } }
 | ||
| 
 | ||
|                     //});
 | ||
|                     ////var channel = GrpcChannel.ForAddress(grpcAdress);
 | ||
|                     //var grpcClient = new TokenGrpcService.TokenGrpcServiceClient(channel);
 | ||
| 
 | ||
|                     //var userInfo = returnModel.Data.BasicInfo;
 | ||
| 
 | ||
|                     //var tokenResponse = grpcClient.GetUserToken(new GetTokenReuqest()
 | ||
|                     //{
 | ||
|                     //    Id = userInfo.Id.ToString(),
 | ||
|                     //    ReviewerCode = userInfo.ReviewerCode,
 | ||
|                     //    IsAdmin = userInfo.IsAdmin,
 | ||
|                     //    RealName = userInfo.RealName,
 | ||
|                     //    UserTypeEnumInt = (int)userInfo.UserTypeEnum,
 | ||
|                     //    UserTypeShortName = userInfo.UserTypeShortName,
 | ||
|                     //    UserName = userInfo.UserName
 | ||
|                     //});
 | ||
| 
 | ||
|                     //returnModel.Data.JWTStr = tokenResponse.Token;
 | ||
| 
 | ||
|                     #endregion
 | ||
| 
 | ||
|                     var userId = returnModel.Data.BasicInfo.IdentityUserId;
 | ||
| 
 | ||
|                     if (_verifyConfig.CurrentValue.OpenLoginMFA)
 | ||
|                     {
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|                         //MFA 发送邮件
 | ||
| 
 | ||
|                         returnModel.Data.IsMFA = true;
 | ||
| 
 | ||
|                         var email = returnModel.Data.BasicInfo.EMail;
 | ||
| 
 | ||
|                         var hiddenEmail = IRCEmailPasswordHelper.MaskEmail(email);
 | ||
| 
 | ||
|                         returnModel.Data.BasicInfo.EMail = hiddenEmail;
 | ||
| 
 | ||
|                         //修改密码
 | ||
|                         if (returnModel.Data.BasicInfo.IsFirstAdd || returnModel.Data.BasicInfo.LoginState == 1)
 | ||
|                         {
 | ||
|                             returnModel.Data.JWTStr = _tokenService.GetToken(_mapper.Map<UserTokenInfo>(returnModel.Data.BasicInfo));
 | ||
|                         }
 | ||
|                         else
 | ||
|                         {
 | ||
|                             //正常登录才发送邮件
 | ||
|                             await _userService.SendMFAEmail(userId);
 | ||
| 
 | ||
|                         }
 | ||
| 
 | ||
|                     }
 | ||
|                     else
 | ||
|                     {
 | ||
|                         returnModel.Data.JWTStr = _tokenService.GetToken(_mapper.Map<UserTokenInfo>(returnModel.Data.BasicInfo));
 | ||
| 
 | ||
|                         // 创建一个 CookieOptions 对象,用于设置 Cookie 的属性
 | ||
|                         var option = new CookieOptions
 | ||
|                         {
 | ||
|                             Expires = DateTime.Now.AddMonths(1), // 设置过期时间为 30 分钟之后
 | ||
|                             HttpOnly = false, // 确保 cookie 只能通过 HTTP 访问
 | ||
|                             SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None, // 设置 SameSite 属性
 | ||
|                             Secure = false // 确保 cookie 只能通过 HTTPS 访问
 | ||
|                         };
 | ||
| 
 | ||
|                         HttpContext.Response.Cookies.Append("access_token", returnModel.Data.JWTStr, option);
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|                         // 验证阅片休息时间
 | ||
|                         await readingImageTaskService.ResetReadingRestTime(returnModel.Data.BasicInfo.IdentityUserId);
 | ||
| 
 | ||
|                         await _fusionCache.SetAsync(CacheKeys.UserToken(userId), returnModel.Data.JWTStr, TimeSpan.FromDays(7));
 | ||
| 
 | ||
|                         await _fusionCache.SetAsync(CacheKeys.UserAutoLoginOut(userId), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TimeSpan.FromMinutes(_verifyConfig.CurrentValue.AutoLoginOutMinutes));
 | ||
|                     }
 | ||
| 
 | ||
|                 }
 | ||
| 
 | ||
|                 returnModel.Data.CompanyInfo = companyInfo;
 | ||
|                 return returnModel;
 | ||
| 
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
|         [AllowAnonymous]
 | ||
|         [HttpGet, Route("user/getPublicKey")]
 | ||
|         public IResponseOutput GetPublicKey([FromServices] IOptionsMonitor<IRCEncreptOption> _IRCEncreptOption)
 | ||
|         {
 | ||
|             //var pemPublicKey = Encoding.UTF8.GetString(Convert.FromBase64String(_IRCEncreptOption.CurrentValue.Base64RSAPublicKey));
 | ||
| 
 | ||
|             return ResponseOutput.Ok(_IRCEncreptOption.CurrentValue.Base64RSAPublicKey);
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         [HttpGet, Route("imageShare/ShareImage")]
 | ||
|         [AllowAnonymous]
 | ||
|         public IResponseOutput ShareImage([FromServices] ITokenService _tokenService)
 | ||
|         {
 | ||
|             var token = _tokenService.GetToken(new UserTokenInfo()
 | ||
|             {
 | ||
|                 UserRoleId = Guid.NewGuid(),
 | ||
|                 UserName = "Share001",
 | ||
|                 UserTypeEnum = UserTypeEnum.ShareImage,
 | ||
| 
 | ||
|             });
 | ||
|             return ResponseOutput.Ok("/showdicom?studyId=f7b67793-8155-0223-2f15-118f2642efb8&type=Share&token=" + token);
 | ||
|         }
 | ||
| 
 | ||
|         [HttpGet("user/GetObjectStoreToken")]
 | ||
|         public async Task<IResponseOutput> GetObjectStoreTokenAsync([FromServices] IOptionsMonitor<ObjectStoreServiceOptions> options, [FromServices] IOSSService _oSSService)
 | ||
|         {
 | ||
| 
 | ||
|             var result = _oSSService.GetObjectStoreTempToken();
 | ||
| 
 | ||
|             //result.AWS = await GetAWSTemToken(options.CurrentValue);
 | ||
| 
 | ||
|             return ResponseOutput.Ok(result);
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         private async Task<AWSTempToken> GetAWSTemToken(ObjectStoreServiceOptions serviceOption)
 | ||
|         {
 | ||
|             var awsOptions = serviceOption.AWS;
 | ||
| 
 | ||
|             //aws 临时凭证
 | ||
|             // 创建 STS 客户端
 | ||
|             var stsClient = new AmazonSecurityTokenServiceClient(awsOptions.AccessKeyId, awsOptions.SecretAccessKey);
 | ||
| 
 | ||
|             // 使用 AssumeRole 请求临时凭证
 | ||
|             var assumeRoleRequest = new AssumeRoleRequest
 | ||
|             {
 | ||
| 
 | ||
|                 RoleArn = awsOptions.RoleArn, // 角色 ARN
 | ||
|                 RoleSessionName = $"session-name-{NewId.NextGuid()}",
 | ||
|                 DurationSeconds = awsOptions.DurationSeconds          // 临时凭证有效期
 | ||
|             };
 | ||
| 
 | ||
|             var assumeRoleResponse = await stsClient.AssumeRoleAsync(assumeRoleRequest);
 | ||
| 
 | ||
|             var credentials = assumeRoleResponse.Credentials;
 | ||
| 
 | ||
|             var tempToken = new AWSTempToken()
 | ||
|             {
 | ||
|                 AccessKeyId = credentials.AccessKeyId,
 | ||
|                 SecretAccessKey = credentials.SecretAccessKey,
 | ||
|                 SessionToken = credentials.SessionToken,
 | ||
|                 Expiration = credentials.Expiration,
 | ||
|                 Region = awsOptions.Region,
 | ||
|                 BucketName = awsOptions.BucketName,
 | ||
|                 EndPoint = awsOptions.EndPoint,
 | ||
|                 ViewEndpoint = awsOptions.ViewEndpoint,
 | ||
| 
 | ||
|             };
 | ||
| 
 | ||
|             return tempToken;
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         [HttpGet("User/UserRedirect")]
 | ||
|         [AllowAnonymous]
 | ||
|         public async Task<IActionResult> UserRedirect([FromServices] IRepository<IdentityUser> _useRepository, string url, [FromServices] ILogger<ExtraController> _logger)
 | ||
|         {
 | ||
| 
 | ||
|             var decodeUrl = System.Web.HttpUtility.UrlDecode(url);
 | ||
| 
 | ||
|             var userId = decodeUrl.Substring(decodeUrl.IndexOf("UserId=") + "UserId=".Length, 36);
 | ||
| 
 | ||
|             var token = decodeUrl.Substring(decodeUrl.IndexOf("access_token=") + "access_token=".Length);
 | ||
| 
 | ||
|             var lang = decodeUrl.Substring(decodeUrl.IndexOf("lang=") + "lang=".Length, 2);
 | ||
| 
 | ||
|             var domainStrList = decodeUrl.Split("/").ToList().Take(3).ToList();
 | ||
| 
 | ||
|             var errorUrl = domainStrList[0] + "//" + domainStrList[2] + "/error";
 | ||
| 
 | ||
| 
 | ||
|             if (!await _useRepository.AnyAsync(t => t.Id == Guid.Parse(userId) && t.EmailToken == token && t.IsFirstAdd))
 | ||
|             {
 | ||
|                 decodeUrl = errorUrl + $"?lang={lang}&ErrorMessage={System.Web.HttpUtility.UrlEncode(lang == "zh" ? "您的初始化链接已过期" : "Error!The initialization link has expired.    Return")} ";
 | ||
|             }
 | ||
| 
 | ||
|             return Redirect(decodeUrl);
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         #region 项目支持Oauth 对接修改
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 回调到前端,前端调用后端的接口 
 | ||
|         /// 参考链接:https://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html
 | ||
|         /// 后端通过这个code ,带上客户端信息,和授权类型  可以向单点登录提供商,获取厂商token
 | ||
|         /// 
 | ||
|         /// 但是单点登录提供商提供的token 和我们系统的token 是有区别的,我们的token里面有我们业务系统的UserId,涉及到很多业务操作,所以在此出现了两种方案
 | ||
|         ///  1、前端使用厂商的Token。          后端通过code 获取厂商的Token 返回前端的同时返回我们系统的UserId,前段在http 请求头加上一个自定义参数,带上UserId  后端取用户Id的地方变动下,
 | ||
|         ///            但是除了UserId外,后端还有其他信息也是从Token取的,所以在请求头也需要带上,此外后端认证Token的方式也需要变化,改造成本稍大(如果是微服务,做这种处理还是可以的)。
 | ||
|         ///  2、前端还是使用我们后台自己的Token。后端通过code 获取厂商Token的同时,后端做一个隐藏登录,返回厂商的Token的同时,也返回我们系统的Token。
 | ||
|         ///  (像我们单体,这种方式最简单,我们用单点登录,无非就是不想记多个系统的密码,自动登录而已,其他不支持的项目改造成本也是最低的)
 | ||
|         /// </summary>
 | ||
|         /// <param name="type">回调的厂商类型 比如github, google, 我们用的logto  ,不同的厂商回调到前端的地址可以不同的,但是请求后端的接口可以是同一个 </param>
 | ||
|         /// <param name="code">在第三方平台登录成功后,回调前端的时候会返回一个code   </param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpGet("User/OAuthCallBack")]
 | ||
|         public async Task<IResponseOutput> OAuthCallBack(string type, string code)
 | ||
|         {
 | ||
|             #region 获取AccessTo
 | ||
| 
 | ||
|             //var headerDic = new Dictionary<string, string>();
 | ||
|             //headerDic.Add("code", code);
 | ||
|             //headerDic.Add("grant_type", "authorization_code");
 | ||
|             //headerDic.Add("redirect_uri", "http://localhost:6100");
 | ||
|             //headerDic.Add("scope", "all");
 | ||
| 
 | ||
|             #endregion
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|             return ResponseOutput.Ok();
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         #endregion
 | ||
| 
 | ||
|         #region 测试获取用户 ip
 | ||
|         [HttpGet, Route("ip")]
 | ||
|         [AllowAnonymous]
 | ||
|         public IResponseOutput Get([FromServices] IHttpContextAccessor _context)
 | ||
|         {
 | ||
| 
 | ||
|             StringBuilder sb = new StringBuilder();
 | ||
|             sb.AppendLine($"RemoteIpAddress:{_context.HttpContext.Connection.RemoteIpAddress}");
 | ||
| 
 | ||
|             if (Request.Headers.ContainsKey("X-Real-IP"))
 | ||
|             {
 | ||
|                 sb.AppendLine($"X-Real-IP:{Request.Headers["X-Real-IP"].ToString()}");
 | ||
|             }
 | ||
| 
 | ||
|             if (Request.Headers.ContainsKey("X-Forwarded-For"))
 | ||
|             {
 | ||
|                 sb.AppendLine($"X-Forwarded-For:{Request.Headers["X-Forwarded-For"].ToString()}");
 | ||
|             }
 | ||
|             return ResponseOutput.Ok(sb.ToString());
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         [HttpGet, Route("ip2")]
 | ||
|         [AllowAnonymous]
 | ||
|         public IResponseOutput Get2([FromServices] IHttpContextAccessor _context)
 | ||
|         {
 | ||
| 
 | ||
|             StringBuilder sb = new StringBuilder();
 | ||
|             sb.AppendLine($"RemoteIpAddress:{_context.HttpContext.Connection.RemoteIpAddress}");
 | ||
| 
 | ||
|             if (Request.Headers.ContainsKey("X-Real-IP"))
 | ||
|             {
 | ||
|                 sb.AppendLine($"X-Real-IP:{Request.Headers["X-Real-IP"].ToString()}");
 | ||
|             }
 | ||
| 
 | ||
|             if (Request.Headers.ContainsKey("X-Forwarded-For"))
 | ||
|             {
 | ||
|                 sb.AppendLine($"X-Forwarded-For:{Request.Headers["X-Forwarded-For"].ToString()}");
 | ||
|             }
 | ||
|             return ResponseOutput.Ok(sb.ToString());
 | ||
|         }
 | ||
|         #endregion
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|     }
 | ||
| }
 |