You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Photoshop API输出至S3签名URL时遇403访问禁止错误

使用AIO Photoshop API调用createRendition的权限问题及后续疑问

问题现象

调用AIO Photoshop API的createRendition生成渲染图时,返回403权限错误:

{ 
  code: 403, 
  details: [ { name: 'https://s3.amazonaws.com/...', reason: 'Unable to upload the outputs' } ], 
  title: 'Access Is Forbidden', 
  type: 'AuthForbidden' 
}

执行结果显示输出状态为failed:

Job { 
  getJobStatus: [Function: bound __getJobStatus] AsyncFunction, 
  url: 'https://image.adobe.io/pie/psdService/status/....', 
  jobId: '...', 
  outputs: [ 
    { 
      input: 'https://s3.amazonaws.com/...', 
      status: 'failed', 
      created: '...', 
      modified: '...', 
      errors: [Object] 
    } 
  ], 
  _links: { self: { href: 'https://image.adobe.io/pie/psdService/status/...' } } 
}

相关代码

主调用逻辑

const util = require('util'); 
const stream = require('stream'); 
const pipeline = util.promisify(stream.pipeline); 
const sdk = require('@adobe/aio-lib-photoshop-api'); 

async function createRenditionOfPSD() { 
  // 生成新的IMSToken
  const authDetails: string = await this.generateIMSToken(clientIdAndApiKey, clientSecret); 
  let authInfo = JSON.parse(authDetails); 
  authToken = authInfo.access_token; 

  // 创建PS API客户端
  const client = await sdk.init(ims, clientIdAndApiKey, authToken); 

  // 获取输入PSD的签名URL
  var signedPSDGetURL = await getSignedUrl(key, bucket); 

  // 创建输出文件的签名URL
  var psdImageKey = id + ".png"; 
  //var signedOutputURL = await getSignedPutUrl(psdImageKey, bucket); 
  var signedOutputURL = await getSignedPostUrl(psdImageKey, bucket); 

  // 配置输入输出参数
  var psdInputOptions = { 
    href: signedPSDGetURL, 
    storage: sdk.Storage.EXTERNAL 
  } 
  var psdOutputOptions = { 
    href: signedOutputURL, 
    type: sdk.MimeType.PNG, 
    storage: sdk.Storage.EXTERNAL, 
    overwrite: true 
  } 

  const renditionResults = await client.createRendition(psdInputOptions, psdOutputOptions); 
  console.log(renditionResults); 

  var outputs = psdRenditionResults.outputs; 
  for (var output in outputs) { 
    var outputItem = outputs[output]; 
    var status = outputItem.status; 
    if (status=="failed") { 
      var errors = outputItem.errors; 
      console.log(errors); 
    } 
    log(output) 
  } 
}

签名URL生成函数

export async function getSignedPutUrl( 
  key: string, 
  bucket: string, 
  expireAfterMinutes: number = 0, 
  options = null,
): Promise<string> { 
  const s3 = new AWS.S3(); 
  var params = { Bucket: bucket, Key: key, }; 
  if (options) { 
    params = Object.assign(params, options); 
  } 
  const url = await s3.getSignedUrlPromise("putObject", params); 
  return url; 
} 

export async function getSignedPostUrl( 
  key: string, 
  bucket: string, 
  expireAfterMinutes: number = 0, 
  options = null,
): Promise<string> { 
  const s3 = new AWS.S3(); 
  var params = { 
    Bucket: bucket, 
    Fields: { 
      Key: key, 
      ContentType: "application/octet-stream", 
    }, 
  }; 
  if (options) { 
    params = Object.assign(params, options); 
  } 
  const presignedPost = await s3.createPresignedPost(params); 
  const url = presignedPost.url; 
  return url; 
}

排查尝试与更新

已尝试过使用PUT签名URL、POST签名URL,也移除了ContentType配置,但最初的403问题仍未解决。

后续找到官方文档,文档指出输出应使用PUT签名URL,但createRendition的示例代码同时存在使用POST和PUT的情况。调整为PUT URL后,现在已能成功保存输出文件,但获取返回的URL时存在问题,推测需要对返回URL进行签名。

相关文档截图:
文档截图1
文档截图2
文档截图3


内容的提问来源于stack exchange,提问作者1.21 gigawatts

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 19:04:53